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:
{ if (standardUserDefaults) { [standardUserDefaults setObject:valueString forKey:key]; [standardUserDefaults synchronize]; } else { NSLog(@"Unable to save %@ = %@ to user defaults", key, valueString); } } { 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 //Get the Preferences Array from the dictionary //Loop through the array NSDictionary *item; for(item in preferencesArray) { //Get the key of the item. //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.
if ([ver compare:kVersionNumber] != NSOrderedSame) { ver = kVersionNumber; [UtilityFunctions saveToUserDefaults:@"version_number" value:kVersionNumber]; }














Comments
Post new comment