NSUserDefaults not saving

ios, nsuserdefaults, sprite-kit

Solution

As rmaddy's answer explains, `NSUserDefaults` won't immediately write data to long-term storage.

The values are saved in temporary memory when you call `setObject:forKey:`, so if you ever try to call `objectForKey:` after `setObject:forKey:`, it will return the value in memory if it exists, and if not, it goes to look for what's been saved to long-term storage.

In the background, the device will eventually save these values to permanent storage. It's something the OS handles, but in normal operation of your app, it shouldn't be necessary to immediately store these values to permanent storage most of the time, so let the OS do this at times when its been optimized to do so (I imagine the OS probably synchs every app's user defaults at once on some regular schedule, and as much as possible, tries to do this when the processor is idle probably).

But with that said, as rmaddy explains, if you've got something that crucially needs to be saved to the permanent storage immediately, you can always call `synchronize`. Keep in mind though... as long as your app isn't killed while in debug mode, the values you've set to be stored in user defaults will be stored.

But for your own sake, if you want to be absolutely certain, you can put it a call to `synchronize` in `applicationDidEnterBackground` as rmaddy suggests. Keep in mind though, this method isn't called if you kill the app.

Problem

I am having a problem in my sprite kit app where my `NSUserDefaults` variable is not working. In `createSceneContents` (which I know is being called) ``` if (![defaults objectForKey:@"obj"]) { difficultyLabel.text = @"Difficulty: Easy"; [defaults setObject:@"Easy" forKey:@"obj"]; } else { difficultyLabel.text = [NSString stringWithFormat:@"Difficulty: %@", [defaults objectForKey:@"diff"]]; } ``` and then when you click on the `SKLabelNode` to change the difficulty and this code is being called ``` if ([label.text isEqualToString:@"Difficulty: Easy"]) { label.text = @"Difficulty: Hard"; [defaults setObject:@"Hard" forKey:@"obj"]; NSLog(@"%@",[defaults objectForKey:@"obj"]); } else { label.text = @"Difficulty: Easy"; [defaults setObject:@"Easy" forKey:@"obj"]; NSLog(@"%@",[defaults objectForKey:@"obj"]); ``` but when I stop the program and run it again, it always just says Difficulty: Easy. Any suggestions?

Original source