Why is NSUserDefaults not saving my values? - iphone

Hi I am trying to use NSUserDefaults to save some default values in database. I am able to save the values in the NSUserDefaults (even checked it in NSLog).
Now I need the values in app delegate when the application is restarted. But I am not getting anything in the NSUserDefaults. Following is my code from my class where I save the values in NSUserDefaults:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:appDel.dictProfile forKey:#"dict"];
NSLog(#"%#",[prefs valueForKey:#"dict"]);
Following is my code from App Delegagte:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSLog(#"%#",[prefs valueForKey:#"dict"]);
the above code always returns me null.
Can some one please help me?

If you terminate your app by pressing the home button (in the Simulator or on the device), your NSUserDefaults will get saved.
If you terminate your app by pressing "Stop" in Xcode (in the Simulator or on the device), your NSUserDefaults might get saved, but there's a good chance they won't. NSUserDefaults persists any changes periodically, and if you terminate the process before they've been persisted, they'll be gone. You can force the save by calling:
[[NSUserDefaults standardUserDefaults] synchronize];
Addendum:
In iOS4 (this answer was originally written when iOS3 was the public release), your NSUserDefaults may not get saved when pressing the home button. Manually calling [[NSUserDefaults standardUserDefaults] synchronize] in applicationDidEnterBackground: should ensure that your NSUserDefaults are saved correctly (this should really be a built-in behaviour IMO).

This code works fine for me .
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
if (standardUserDefaults) {
[standardUserDefaults setObject:myString forKey:#"Prefs"];
[standardUserDefaults synchronize];
}

You didn't say whether you are running on a device or in the simulator, but if you restart the application in the simulator, all preferences will be reset between launches if you launch from Xcode. The preferences will only be preserved if you relaunch from the simulator itself.

In my case I was saving and retrieving a string. When I synchronized after saving and then retrived in another thread, it was not working properly. The problem was solved by synchronizing both after saving and before retreiving.

Related

NSUserDefault doesn't work on real device(iPhone)

In my App, I am trying to implement SettingView by NSUserDefault. So, I wrote program code as follows:
Method example of saving user setting:
+ (void)setUserAutoPlaySetting:(BOOL)setting {
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setBool:setting forKey:kAutoPlaySettingKey];
[userDefaults synchronize];
}
This method is received user setting as BOOL and saves by NSUserDefault.
I confirmed my App save user setting on simulator but not on real Device.
In addition, this method is enable to save NO but disable to save YES on a real device.
Can anyone please tell how can I overcome this problem? Thanks.

Strange iPhone SDK NSUserDefaults behaviour

I'm experiencing some strange NSUserDefaults behaviour. I save my data, then synchronize, then do a NSlog of the NSUserDefaults to make sure its saved. The data is shown as saved properly from the NSlog, but when I completely close the app (double click home button and kill the app) when it restarts the value has not changed. Whats even stranger is if I repeat the code several times by saving NSUserDefaults, killing the app, reloading the NSUserDefaults sometimes it gets saved properly and other times it does not.
I read this post Strange NSUserDefaults behavior but I am calling synchronize so I don't think thats my problem.
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:#"MyString" forKey:#"testString"];
[[NSUserDefaults standardUserDefaults] synchronize];
NSLog(#"%#", [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]);
Any help is greatly appreciated.
What really confuses me is if the NSLog of standardUserDefaults shows the data is saved why wouldn't it be after the app has been killed???
Thanks
UPDATE
Looks like the issue was with a mixup in mutable and immutable arrays i was saving to NSUserDefaults. I used mutablecopy when I was retrieving the data and seemed to solve the issue.
For getting the value you could use something like this
NSUserDEfaults *ud = [NSUserDefault standarUserDefaults];
[ud objectForKey=#"YourKey"];
If it returns nil it hasn't been saved.

Consistent NSUserDefaults saving

So in my app, I was saving some integer keys in NSUserDefaults,like around a minimum of 20.
Something like this but many:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setInteger:1 forKey:#"game1"];
[prefs setInteger:1 forKey:#"game2"];
[prefs setInteger:1 forKey:#"game3"];
So I was just wondering, should I call:
[[NSUserDefaults standardUserDefaults] synchronize];
Everytime I save?
Because sometimes I'm experiencing an inconsistency of the integer I'm saving and have been loading either with stopping, running the app in xCode or from the Home Button.
I have read a couple of articles on a site that stated:
In iOS4, your User Defaults may not get saved when pressing the home button. Manually calling [[NSUserDefaults standardUserDefaults] synchronize] in applicationDidEnterBackground: should ensure that your User Defaults is saved correctly.
Is this true and the same in iOS5? Or are there more accurate ways, shorter ways of saving integers. Thanks for the help.
Apple's documentation says this:
"Because this method is automatically invoked at periodic intervals, use this method only if you cannot wait for the automatic synchronization (for example, if your application is about to exit) or if you want to update the user defaults to what is on disk even though you have not made any changes."
So, depending on the urgency of the data you are settings, you may of may not need to call synchronize. Full documentation is here.
No you don't need to, when you call setInteger:forKey: on prefs, it automatically gets saved.

Change application settings through settings bundle while application is running IOS

I have written code in -(void)applicationWillEnterForeground:(UIApplication *)application , but my application is not detecting the change made in the settings bundle, new settings work when application restarts, someone please help me how to make changes in application's settings while application is running
Try to -(BOOL)synchronize; the NSUserDefaults.
After setting the values in NSUserDefaults try calling [[NSUserDefaults standardUserDefaults] synchronize]; so that the values get written to disk.
in your applicationWillEnterForeground: methode after this line
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults], add this line
[defaults synchronize];

applicationWillTerminate works as long as I don't switch off the iPhone

to save some variables of my apps I use:
-(void)applicationWillTerminate:(UIApplication *)application {
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setFloat: self.viewController.sLabel.contentOffset.y forKey:#"floatKey"];
[prefs setObject:self.viewController.newText forKey:#"stringVal"];
[prefs synchronize];
}
and to retrieve them, via a button, I do the following:
-(IBAction) riprendi:(id) sender {
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
float myFloat = [prefs floatForKey:#"floatKey"];
//some actions here
}
Everything is working on the simulator. However, using it on a real iPhone, the variables' saving and retrieving works just if you press the Home button, exiting the app and opening again but NOT if you switch off/on the iPhone. In this case, the variables get simply lost once you re-open the app...
What am I missing?? This is actually driving me crazy :(
Thank you so much ;)
Fabio
If you mean hitting the lock button on the top of the phone by saying "switching on/off", then it won't work, because locking the phone does not cause an application to quit.
Your applicationWillTerminate: method is only called when you exit you're application to the home screen or to some other application. When the user presses the Sleep button, applicationWillResignActive: will be send to your application-delegate.
Apple's iPhone OS Programming Guide has a section on handling interruptions.
According to Apple's documentation
"NSUserDefaults caches the information to avoid having to open the user’s defaults database each time you need a default value."
If you want to make sure things are saved you should call "synchronize" on your prefs.