In iOS4, when I save NSUserDefaults, the information gets saved. But then, if the application becomes inactive, and I kill the application (by double clicking the home button and then terminating the app), and launch the application again, the NSUserDefaults are not read.
Now, is this the default behaviour of NSUserDefaults that if the app is terminated due to any of the issues, the next launch will not store the information?
The call I am using to persist the info is:-
[[NSUserDefaults standardUserDefaults] registerDefaults:
[NSDictionary dictionaryWithObjectsAndKeys:
"Some date", #"Validity",
nil]];
after you register defaults add this
[[NSUserDefaults standardUserDefaults] synchronize];
until you synchoronize, the standardUserDefaults gives current/correct values as long as the app is alive.
once the app is terminated, since you didn't sync the standardUserDefaults, the app will read the unsynced values on the next launch.
Example: Think of it like a google doc that you are editing.
the AutoSave feature of google document is equivalent to the nsuserdefaults synchornize. If you close the browser before the changes you made to the document has been autosaved, the next time you load it up, you'll see the old content.
The call you mention to persist the user defaults, registerDefaults, does not actually persist anything to disk. What registerDefaults does is initialize the defaults to use for the application if it can't find any on the disk. You should do this on each application launch, typically in the initialize method for the app delegate.
Once your application is running it will typically modify the user defaults. Whenever you want to save these modified defaults to the disk you should call:
[[NSUserDefaults standardUserDefaults] synchronize];
After the defaults have been saved they will be loaded automatically on any subsequent application launches.
Related
I'm writing a feature of the language change. First screen of the app I'm writing is about setting the language. When he user presses the button, my app directs user to app settings. I expect user to set some language and show it to them as soon as they go back to my app.
But as soon as I click on some language option, my app xcode console says:
Message from debugger: Terminated due to signal 9
Additionally, as soon as I return to my app, it gets loaded as if I closed and reopened it.
I thought that maybe I can have some code that will set a global variables like "currentLanguage" and "previousLanguage" and if those are different - I will load localisation files for "currentLanguage" and will start downloading localised videos from my server.
System terminate your app when user change language in Settings. So you can use NSUserDefaults for persistent storage and compare this values on app start, to detect if language was changed.
Example:
NSString *currentLanguage = [[NSLocale preferredLanguages] firstObject];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject: currentLanguage forKey:#"previousLanguage"];
NSString *previousLanguage = [userDefaults objectForKey:"previousLanguage"];
Once I kill application then I want to Clear data from NSUserDefaults, but sometimes it is not getting cleared.
I have added the code into this method :
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
[[NSUserDefaults standardUserDefaults]removeObjectForKey:kcoupondic];
[[NSUserDefaults standardUserDefaults] synchronize];
}
Why are you using NSUserDefaults if you want to clear values on app termination.
Use global variable instead of NSUserDefaults
OR
If you wan't to remove all NSUserDefaults try this:
[[NSUserDefaults standardUserDefaults] removePersistentDomainForName:[[NSBundle mainBundle] bundleIdentifier]];
applicationWillTerminate is not always called. This is from Apple's documentation.
This method lets your app know that it is about to be terminated and purged from memory entirely. You should use this method to perform any final clean-up tasks for your app, such as freeing shared resources, saving user data, and invalidating timers. Your implementation of this method has approximately five seconds to perform any tasks and return. If the method does not return before time expires, the system may kill the process altogether.
For apps that do not support background execution or are linked against iOS 3.x or earlier, this method is always called when the user quits the app. For apps that support background execution, this method is generally not called when the user quits the app because the app simply moves to the background in that case. However, this method may be called in situations where the app is running in the background (not suspended) and the system needs to terminate it for some reason.
To answer your question as to why your data is not getting cleared, maybe this method is not getting called. Try and add some logs to check if the method gets called.
I would rather put this code in applicationDidFinishLaunchingWithOptions inside AppDelegate. In this case, you're sure that at every app launch you'll clear this data before you re-populate it.
For Swift:
if let bundleId = Bundle.main.bundleIdentifier {
UserDefaults.standard.removePersistentDomain(forName: bundleId)
}
Here, we are optional unwrap bundleIdentifier to prevent crash.
Try writing your code to clear NSUserDefaults in applicationWillResignActive instead of applicationWillTerminate.
I'm trying to make a Core Data persistence store logic where:
If it's the first time the user is launching the app, all the data gets generated inside the app and gets loaded (and when he/she exists app, that's the first time the data is getting saved to the persistent store)
If it's not the first time the user is launching the app, then all the data gets loaded from existing Core Data persistent store.
How would you check if it's the first time the user is launching the app?
You can store the information with NSUserDefaults.
You set a variable to TRUE when the app launches for the first time.
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
if([userDefaults boolForKey:#"notFirstLaunch"] == false)
{
//do stuff on first launch.
[userDefaults setBool:YES forKey:#"notFirstLaunch"];
[userDefaults synchronize];
}
You can also store the app Version to update the database on App updates.
This tutorial is big help.
Core Data on iOS 5 Tutorial: How To Preload and Import Existing Data
I have an ios app, and recently have been getting some reports from users about their settings getting reset.
The settings are saved using NSUserDefaults.
My question is, can the user defaults get corrupt/reset for some reason?
A few notes about how I use it:
When I start my app, I store default values only if the keys doesn't exist using registerDefaults (this is done to take care of the "first install" scenario).
Most of the aforementioned reports describe the app crashing, and then when it is reopened the settings are reset to default.
My usage of NSUserDefaults is pretty straightforward - saving numbers/strings, reading them sometimes, etc. Nothing too fancy. I don't remove keys.
Some code examples:
For example, I'm saving the data in different places using:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:#"FirstLevel" forKey:#"Level"];
[defaults setInteger:100 forKey:#"Score"];
[defaults synchronize];
I read using:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
int intValue = [defaults integerForKey:#"Score"];
return intValue;
So, can something cause the user defaults to get reset/corrupt somehow?
More generally, can it be related to the app crashing that was reported, even if the crash is not directly as a result of writing/reading from user defaults?
From what I understand, it is only swiped out when app is deleted. Since your NSUserDefaults' reset issue was preceding by the app crashed, I would start by figure out the crashing issue.
If you install your app in your device the NSUserDefault will be Re initialized again… when ever you test your app in device you will connect your device with Xcode and if you run the program the values will be reset…
We are developing an iPhone application. The app is available in the app store. We are using NSUserDefaults to store our usertoken value. But some users reports that the usertoken is became null when the app idle (in background) for long time. But normally the value is getting.
The following is the code for storing usertoken in the NSUserDefaults. We are setting the value to the userToken from the login page and signup pages.
[[NSUserDefaults standardUserDefaults] setObject:userToken forKey:USER_TOEKN];
I have not called synchronize after setting value to NSUserDefaults. Could you please help
You need to call [[NSUserDefaults standardUserDefaults] synchronize]; if your app is going to be backgrounded - my guess is the app idles before the defaults automatically synchronizes. From the documentation:
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.
As for where to do this, take a look at applicationWillResignActive: and applicationDidEnterBackground: in your Application Delegate.
Try something like this:
NSUserDefaults *udf = [NSUserDefaults standardUserDefaults];
[udf setObject:userToken forKey:USER_TOEKN];
[udf synchronize];
It will store your value permanently.