Thursday, October 23, 2008

Default user settings for iPhone apps

The iPhone SDK allows you to define application settings and their default values in a system bundle.  There are several good tutorials that teach you how to do this, and you can also study Apple's AppPerf sample code.  Unfortunately, the current iPhone OS (as of 2.2 beta) doesn't automatically initialize the settings to your defaults.  See this Apple discussion thread for more details.  This sure seems like an oversight, but for now it's up to you to properly initialize the values.  

The AppPerf sample does handle the initialization case, but in a hardcoded and nonpersistent way.  My solution was to write a function that builds up a dictionary of default values by parsing the solution bundle.   Just call this method instead of NSUserDefaults:standardUserDefaults and pass in the name of one of your keys.

- (NSUserDefaults *) loadUserSettings:(NSString *)aKey

{

// Load user settings

NSUserDefaults *settings = [NSUserDefaults standardUserDefaults];

if (![settings stringForKey:aKey])

{

// The settings haven't been initialized, so manually init them based

// the contents of the the settings bundle

NSString *bundle = [[[NSBundle mainBundle] bundlePath]

stringByAppendingPathComponent:@"Settings.bundle/Root.plist"];

NSDictionary *plist = [[NSDictionary dictionaryWithContentsOfFile:bundle]

objectForKey:@"PreferenceSpecifiers"];

NSMutableDictionary *defaults = [NSMutableDictionary new];

// Loop through the bundle settings preferences and pull out the key/default pairs

for (NSDictionary* setting in plist)

{

NSString *key = [setting objectForKey:@"Key"];

if (key)

[defaults setObject:[setting objectForKey:@"DefaultValue"] forKey:key];

}

// Persist the newly initialized default settings and reload them

[settings setPersistentDomain:defaults forName:[[NSBundle mainBundle] bundleIdentifier]];

settings = [NSUserDefaults standardUserDefaults];

}

return settings;

}