NSUserDefaults not working on iPhone 4.0 device? - iphone

i am using NSUserDefaults to save data from the app and when the user leaves the app and then come back to it all the values are restored.
the thing is that it does save the values while the app is running in background mode. but when i close the app from multitasking and re-open it the app comes back as new with no values saved. i have added the methods beginInBackground and applicationWillterminate
but no help is their a new way of doing this on the new 4.0?
PS. i am testing on the device only. i could not use the simulator because i am using Map kit.

Are you calling the synchronize method?

In your applicationDidEnterBackground just use the following code:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults synchronize];

The problem you are having is that you are expecting an NSApplicationWillTerminateNotification that is not getting sent in 4.0 because NSApplicationDidEnterBackgroundNotification is getting sent instead. I have had the same problem. Register both notifications for your storage function and it will work again. You don't need conditional code since even if you register for a notification that does not exist in 3.0, it will never get called there so there will be no crash.
If you are not using notifications you can also override applicationDidEnterBackground: as noted in the above comment.

Related

Alternative to InAppSettingsKit

Is there an alternative to InAppSettingsKit that is simpler? I find myself needing only 20% of what it offers.
How about ESCOZ's QuickDialog library? Seems like a reasonable alternative.
Well, one alternative is to just build your own settings panel with a regular UIViewController and some buttons and switches, etc. and then save the settings using NSUserDefaults, e.g.
- (IBAction)mySettingSwitchAction:(UISwitch *)theSwitch
{
//save the switch setting
[[NSUserDefaults standardUserDefaults] setBool:theSwitch.on forKey:#"myPreferenceName"];
}
then you can load it again anywhere in your app using
BOOL theValueISet = [[NSUserDefaults standardUserDefaults] boolForKey:#"myPreferenceName"];
Values you set in NSUserDefaults are persistent so if the app is closed and opened again they retain their values. You can call synchronize on NSUserDefaults to force it to save/load the values but this happens automatically on app open/close anyway.

Storing Last Launch

I am trying to store the last launch date of my app. So I did the following:
- (void)applicationWillResignActive:(UIApplication *)application {
NSDate *today = [NSDate date];
[[NSUserDefaults standardUserDefaults] setObject:today forKey:#"lastLaunch"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
However, when I relaunch the app again and print out the object for key lastLaunch it shows null. Why isn't it storing the date? Am I putting it in the wrong method? I am running it and terminating the app from Xcode.
applicationWillResignActive: is also called when you receive phone call...
You can find more info here:
http://www.cocoanetics.com/2010/07/understanding-ios-4-backgrounding-and-delegate-messaging/
I think that applicationDidEnterBackground is a better place to put your code because user can deny phone call and go back to your app...
And for iOS3 users without multitasking watch for applicationWillTerminate:
Stop in Xcode just kills your application without calling anything...
NSUserDefaults is weird in the iPhone simulator. I expect your code to work on an actual device.

Remember Apps last screen in iPhone app

I want to remember the last screen of my app, means if I reopen my app, app should navigate me to the last screen where I were just before exiting app.
Thanks
Saurabh
Take a look at the NSUserDefaults API.
You could save an object for the current screen in the NSUserDefaults then check for that object on launch.
Create a NSMutableDictionary object when a view loads, and change it's value each time, and store it in the user defaults.
NSMutableDictionary *currentScreen = [[NSMutableDictionary alloc] init];
[currentScreen setObject:#"AboutPage" forKey:#"screen"];
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
[standardUserDefaults setObject:currentScreen forKey:#"lastScreen"];
Then when the app loads, check the user defaults "lastScreen" key and load the appropriate view.
Hope this helps.
in iOS4 it's done automatically, because when you quit your application it's actually enters the background mode and doesn't quit. So when you "launch" it again, it opens at the same place the user left.
Previous versions of iOS don't have this feature and you should take care of it by yourself.
Depending on your application, you may want to think about using the Three20 library. This library has the sort of persistence you are looking for built in.

Why won't my NSUserDefaults load?

So I have an iphone app that presents a modal view when it starts if the user has not registered. Once they register, it saves a user ID into NSUserDefaults. When the app starts at a later time, it needs to load this user id in the appdelegate file.
//Registration.m
NSUserDefaults *savedUID = [NSUserDefaults standardUserDefaults];
[savedUID setObject:UID forKey:#"user_id"];
//AuctionTracAppDelegate.m
NSUserDefaults *savedID = [NSUserDefaults standardUserDefaults];
NSString *uidString = [savedID stringForKey:#"user_id"];
My problem is that when I try to load this value at a separate execution, the object I saved is always null. I know for a fact that it is saving the string object correctly. Also, this weird behavior JUST surfaced. This exact code was working earlier, then after working on a totally unrelated file, this code fails. I'm clueless as to what happened. Any hints?
I believe that you need to call the synchronize method.

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.