9

I am developing an iPhone application, I encounter a problem on the iOS4 because of multi task.

This application has the default settings defined in a Settings.bundle. If I run my application then I left it (so it goes in the background). I'll change the settings and restarts the application (it comes out of standby and method: applicationDidBecomeActive () is called).

Values in NSUserDefault are not updates, but when I leave the application and relaunch. The values are good.

Does someone experience the same problem as me? Is what I'm doing something wrong?

Thank you for your advice / help.

Douwe Maan
  • 6,888
  • 2
  • 34
  • 35
Mathieu Mahé
  • 2,647
  • 3
  • 35
  • 50
  • Are you refreshing the defaults once your app becomes active again? If you're not, then you should incase they changed while in the background. – iwasrobbed Jul 07 '10 at 13:48

2 Answers2

20

I had the same problem as you, and got around it by calling

[[NSUserDefaults standardUserDefaults] synchronize];

in applicationDidBecomeActive.

For some reason the [NSUserDefaults standardUserDefaults] object you can access in your app isn't synchronized with the actual plist files backing it when an app becomes active again after having been suspended. Calling the synchronize method forces a synchronization.

Douwe Maan
  • 6,888
  • 2
  • 34
  • 35
  • It's important to emphasize that synchronize MUST be called after you change NSUserDefaults if you want to write those changes to a file. If you don't the changes will be just stored in memory. – Goles Jul 21 '10 at 17:08
  • 1
    @Mr.Gando That's just not true. `NSUserDefaults` is also periodically synchronized to file automatically. – Douwe Maan Dec 22 '10 at 08:55
3

You need to listen for settings changes. Best way to do it is to set up a listener wherever you need it:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(settingsChanged) name:NSUserDefaultsDidChangeNotification object:nil];

The only thing you need to make sure of is that you don't change any settings in your listener, or you get infinite recursion without a little more logic being added in.

I'd stay away from synchronizing because in my experience I found I had to run it twice. But that's accidental behavior. A listener will notify you when the new settings have been re-read from the store.

ZaBlanc
  • 4,679
  • 1
  • 35
  • 38
  • The downside to using this, is that it also fires when you change anything about `NSUserDefaults` yourself. So every time you call `[[NSUserDefaults standardUserDefaults] setObject:someObject forKey:@"someKey"]` this notification is broadcast, and the method is called. Which is not what I (and presumably the asker) wants. Also, I haven't had any problems with `synchronize`, calling it only once worked fine. – Douwe Maan Jul 10 '10 at 16:09
  • This way is obviously better. Just update user-defaults, and do behavior change only in notification observer. And also, you have to apply any user-deafult changes in real-time during application running with multitasking of iOS4. – eonil Oct 08 '10 at 08:54