Updating NSUserDefaults from Settings.bundle
Trying to access parameters from Root.plist in your Settings.bundle using NSUserDefaults? Luckily NSUserDefaults will sync those values for you ... after the user opens the Settings preferences for your app first. As pointed out here, among a few other spots, that certainly seems like a bug, or at least yet another expectation gap. I know the first thing I do when I download an app is run over to the Settings to see what goodness I can configure.... Sheesh.
So to make it easier for me to not have to check, I blended some of the code from Richard Greene's post above with the example from CocoaDev to give me this nice wrapper:
+ (void)saveToUserDefaults:(NSString*)key value:(NSString*)valueString
{
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
if (standardUserDefaults) {
[standardUserDefaults setObject:valueString forKey:key];
[standardUserDefaults synchronize];
} else {
NSLog(@"Unable to save %@ = %@ to user defaults", key, valueString);
}
}
+ (NSString*)retrieveFromUserDefaults:(NSString*)key
{
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
NSString *val = nil;
if (standardUserDefaults)
val = [standardUserDefaults objectForKey:key];
// TODO: / apparent Apple bug: if user hasn't opened Settings for this app yet (as if?!), then
// the defaults haven't been copied in yet. So do so here. Adds another null check
// for every retrieve, but should only trip the first time
if (val == nil) {
NSLog(@"user defaults may not have been loaded from Settings.bundle ... doing that now ...");
//Get the bundle path
NSString *bPath = [[NSBundle mainBundle] bundlePath];
NSString *settingsPath = [bPath stringByAppendingPathComponent:@"Settings.bundle"];
NSString *plistFile = [settingsPath stringByAppendingPathComponent:@"Root.plist"];
//Get the Preferences Array from the dictionary
NSDictionary *settingsDictionary = [NSDictionary dictionaryWithContentsOfFile:plistFile];
NSArray *preferencesArray = [settingsDictionary objectForKey:@"PreferenceSpecifiers"];
//Loop through the array
NSDictionary *item;
for(item in preferencesArray)
{
//Get the key of the item.
NSString *keyValue = [item objectForKey:@"Key"];
//Get the default value specified in the plist file.
id defaultValue = [item objectForKey:@"DefaultValue"];
if (keyValue && defaultValue) {
[standardUserDefaults setObject:defaultValue forKey:keyValue];
if ([keyValue compare:key] == NSOrderedSame)
val = defaultValue;
}
}
[standardUserDefaults synchronize];
}
return val;
}Here's how I'm using it, for reference. This block is in my root controller's viewDidLoad method. It checks the value of the app's version number as stored in the userDefaults, but compares to a #define var. Why? Because apparently once you set a PSTitleValueSpecifier preference, you can't change it by editing the plist in Settings.bundle. Ugh.
NSString *ver = [UtilityFunctions retrieveFromUserDefaults:@"version_number"];
if ([ver compare:kVersionNumber] != NSOrderedSame) {
ver = kVersionNumber;
[UtilityFunctions saveToUserDefaults:@"version_number" value:kVersionNumber];
}
Comments
Pingback
[...] See this article. [...]
Pingback
[...] http://greghaygood.com/2009/03/09/updating-nsuserdefaults-from-settingsb... [...]
Pingback
[...] http://greghaygood.com/2009/03/09/updating-nsuserdefaults-from-settingsb... [...]
Pingback
[...] Updating NSUserDefaults from Settings.bundle | greg haygood greghaygood.com/2009/03/09/updating-nsuserdefaults-from-settingsbundle – view page – cached Trying to access parameters from Root.plist in your Settings.bundle using NSUserDefaults? Luckily NSUserDefaults will sync those values for you ... Tweets about this link Topsy.Data.Twitter.User['tomonarishimada'] = {"location":"","photo":"http://a1.twimg.com/profile_images/518812310/5920_1078842333207_1290747434_174144_2459076_n_normal.jpg","name":"Tomonari Shimada","url":"http://twitter.com/tomonarishimada","nick":"tomonarishimada","description":"","influence":""}; tomonarishimada: “解決方法はこちら http://bit.ly/dnB69S よく出来ました。 ” 5 days ago view tweet retweet Filter tweets [...]
Post new comment