iPhone preferences (NSUserDefaults) not working, keys always return nil
I made some preferences in my Setting开发者_如何学Cs.bundle that show up fine in the Settings app. However my settings always return nil when I read them back. I know I need to set a default value on first startup. But even after that and going to the settings menu (which should also set the default values) - when I read them back I always get nil.
Even when I set the default and read it back immediately I get nil!
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:@"YES" forKey:@"displaySunTimes"];
[defaults registerDefaults:appDefaults];
[defaults synchronize];
bool test =[defaults boolForKey:@"displaySunTimes"];
NSLog(@" Value %@", test);
Here's the beginning of my root.plist
<dict>
<key>StringsTable</key>
<string>Root</string>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>Type</key>
<string>PSGroupSpecifier</string>
<key>Title</key>
<string>Display Sunrise / Sunset times for your location.</string>
</dict>
<dict>
<key>Type</key>
<string>PSToggleSwitchSpecifier</string>
<key>Title</key>
<string>Sunrise / Sunset</string>
<key>Key</key>
<string>displaySunTimes</string>
<key>DefaultValue</key>
<true/>
<key>TrueValue</key>
<string>YES</string>
<key>FalseValue</key>
<string>NO</string>
</dict>
If you want to store a BOOL then use:
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"displaySunTimes"];
In order to retrieve it from defaults:
[[NSUserDefaults standardUserDefaults] boolForKey:@"displaySunTimes"];
EDIT:
Change the NSLog(@" Value %@", test);
to NSLog(@" Value %i", test);
(BOOL is not an object).
In addition, use BOOL
instead of bool
.
It helps if you understand the difference between @"YES"
, [NSNumber numberWithBOOL:YES]
, and YES
.
In this case, it's returning "NO" ((BOOL)0
), not "nil" ((id)0
). Use objectForKey:
if you want to know if something is stored at all. In this case, you are storing the NSString @"YES" and trying to read it as a bool; I refer you to the docs for boolForKey:
If a boolean value is associated with defaultName in the user defaults, that value is returned. Otherwise, NO is returned.
A string is not a boolean, so @"YES" becomes NO. Try something like this:
NSDictionary *appDefaults = [NSDictionary dictionaryWithObject:[NSNumber numberWithBOOL:YES] forKey:@"displaySunTimes"];
A little odd to be using a String to represent a bool value.
TryAs others pointed out (and I'd forgotten), use the[NSNumber numberWithBOOL: YES]
instead.boolForKey:
andsetBool:forKey:
APIs on NSUserDefaults.When I've run into something like this it is because I somehow managed to push the wrong defaults value into the defaults database. Are you sure you don't have a default value from a previous run sticking around?
Registration defaults are the default value to use when a value has not been previously set.
Unless the app and all data is being deleted between each run, then this still sounds exactly like you have a default value already set and the registration default isn't overriding it (correct behavior).
Try manually setting the default to some other value and synchronizing.
Note also that synchronize
is completely orthogonal to registration defaults.
精彩评论