NSUserDefaults (Preferences)

Not everybody likes their applications to behave in the same way, and this is why the majority of Mac and iPhone applications have preferences. The default way to handle these preferences is using the class NSUserDefaults.

NSUserDefaults are stored on the file system as .plist, which is simply an XML document. The way you access NSUserDefaults programatically is very much like accessing an NSMutableDictionary, that is by using keys.

Setting User Defaults

NSUserDefaults can be a bool, float, integer or an object. So if you wanted to set the autosave option (which is a BOOL) for your application to be YES, you would write:

[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"AutoSave"];

Moreover if you wanted to set the person’s name to ObjColumnist you would write:

[[NSUserDefaults standardUserDefaults] setObject:@"ObjColumnist" forKey:@"PersonName"];

Reading User Defaults

Reading the user defaults is just as easy as setting them. If we wanted to retrieve the 2 values we stored above, you would simply write:

NSString *name = [[NSUserDefaults standardUserDefaults] stringForKey:@"PersonName"];
BOOL autoSave = [[NSUserDefaults standardUserDefaults] boolForKey:@"AutoSave"];

You should also notice that there is a convenience method for retrieving a string for a key, even though we set it as an object.

It is also important to be aware that if you attempt to retrieve a numeric value such as an integer, integerForKey: for a non existent key, you will get the value 0. This is obviously an issue if 0 would trigger a certain preference in you application.

Setting the default user defaults

So you can now set and read the user defaults, but how do you assign their default values ?

The answer is registerDefaults:

This method is usually called in the initialize (class) method of a given application’s AppController. The parameter for this method is an NSDictionary. The code below sets the default preference for the AutoSave option to YES, and the person’s name to @“unknown”.

NSMutableDictionary *defaults = [NSMutableDictionary dictionary];

[defaults setObject:[NSNumber numberWithBool:YES] forKey:@"AutoSave"];
[defaults setObject:@"unknown" forKey:@"PersonName"];

[[NSUserDefaults standardUserDefaults] registerDefaults: defaults];

One thing that Cocoa does for you automatically without needing any extra code, is that it only saves to the .plist the values that are different to the defaults values, that were registered using registerDefaults: . This means that if the user does not change any of their default preference settings, there will no be a preference file created.

Note: The code above just stores the preference for the AutoSave option, you still have to create the code to manage the saving of data yourself.