views:

2050

answers:

3

I have an AppDelegate class with +(void)initialize method that I use to register some defaults. Here's the code that I use:

+ (void)initialize {
  NSDictionary *defaults = [NSDictionary dictionaryWithObjectsAndKeys:@"NO", @"fooKey", @"YES", @"barKey", nil];

  [[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
}

I also created Preferences.xib which holds couple of checkboxes (NSButton) that display status of preferences. They are bound to NSUserDefaultsController with same keys (fooKey and barKey in this case). Each time I launch an app and change the "defaults" they are restored on next app launch.

Is there a way to register "default defaults" without overwriting already existing values? Maybe each time I build and launch an app its preferences file is being recreated? Maybe I should unbind checkboxes from NSUserDefaultsController and maintain the values of keys myself with some custom code in preferences window controller?

I'd like to hear your implementation of choice for maintaining user defaults.

I'm using Mac OS X 10.6.2 and XCode 3.2.1

A: 
Laurent Etiemble
There's a bit of confusion. You have two methods that loads and saves user defaults if I understood you correctly. I'm looking for a third method that creates user defaults if they weren't already created. Now I see there's no explicit method for this. Calling `registerDefaults:` when a key is not present is okay for one or two keys, but when there are much more preferences it becomes PITA to maintain those checks (at least I can think of one big `if` statement).Thanks for your thoughts!
Eimantas
Right. Now I get your point. Before register defaults for the first time they wouldn't have ANY key at all. Silly me! ^.^
Eimantas
This is wrong. There is no need to test if any preference has been set already. `-registerDefaults:` will not override preferences already set.
Johan Kool
+7  A: 

From the documentation for -registerDefaults: (emphasis added):

The contents of the registration domain are not written to disk; you need to call this method each time your application starts. You can place a plist file in the application's Resources directory and call registerDefaults: with the contents that you read in from that file.

So your code was on the right track. This is how you register default defaults.

I usually use this in -applicationDidFinishLaunching::

    // Load default defaults
    [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Defaults" ofType:@"plist"]]];

Using a plist makes it easy to add and change defaults in your app, and it prevents you from making the mistake of using @"NO" as a value too.

Johan Kool
Johan - thanks for the eye-opener. I rechecked the call and it seems that it works without any if statements!
Eimantas
A: 

@Johan Kool: Can your "load default defaults" code above be used with the Settings bundle? For example, could I use the Root.plist file to initialize my defaults?

Ricky
Yes, though your Settings bundle may be loaded before you app was ever launched, so you still may want to set the initial defaults in the settings plist as well. The `-registerDefaults:` method will not override preferences set through a Settings bundle.
Johan Kool