English 中文(简体)
iphone dev - NSUserDefaults check for boolean existence
原标题:

I ve just added a settings bundle to my app and am having trouble reading the bool settings. I know that upon launch of the app, the settings are not read unless the user actually enters them - and that s what I am trying to capture.

However, my code is simply capturing if the answer is NO OR they havent been set. I need to find out if they ve been set, THEN set answers!

setting code:

BOOL playSound;
BOOL playVibrate;


//test for some defaults
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
if (![prefs boolForKey:@"pref_sound"]) {
    playSound = YES;
    playVibrate = YES; 
} else {
    playSound = [prefs boolForKey:@"pref_sound"];
    playVibrate = [prefs boolForKey:@"pref_vibrate"]; 
}


if (playSound) {
//do stuff
}

the problem is, if the user sets the settings to "NO", the code then changes both vibrate AND sound to yes - which is meant to be the capture for NOT setting....

any ideas?

最佳回答

First of all you have a bug in your if conditional. You re checking the boolean value itself which, according to the boolForKey: documentation, will return a NO if it s not set yet. So boolForKey: is not the right way to do that.

Here s two other ideas.

Consider using another setting with another key to specify whether your settings have been initialized. Check it when you launch your app, or when you first read a setting. Initialize if needed. For instance:

- (void) initializeUserDefaults {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if (nil == [defaults objectForKey:@"initialized_defaults"]) {
        [defaults setBool:YES forKey:@"pref_sound"];
        [defaults setBool:YES forKey:@"pref_vibrate"];
        [defaults setObject:@"dummy_value" forKey:@"initialized_defaults"];
    }
}

A simpler solution (but I m not sure if this would work) would be to change your conditional to read:

if (![prefs objectForKey:@"pref_sound"]) {

Again I don t know if this will do what I imagine it will, but I imagine that objectForKey: will return the underlying boxed boolean object, if it s there, or nil.

If you add a new setting in a new version of your app, you don t want to leave your new settings uninitialized and you don t want to stomp your users existing settings. This second method makes that effortless, and in the first method it s easier to screw up. But the first method also gathers all your settings in one place so you can see how it s supposed to work, which I like.

I am not sure what ADC docs would consider a best practice though. To find that out, I d suggest you look at any code samples referenced from the NSUserDefaults class reference.

问题回答

maybe the best idea is to register some defaults for the NSUserDefaults using

(void)registerDefaults:(NSDictionary *)dictionary

see Apple Documentation at https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/index.html#//apple_ref/doc/uid/20000318-SW5

To come back to your original problem: in the past I was using NSUserDefaults.dictionaryRepresentation in order to check the existence of a key:

BOOL playSound;
BOOL playVibrate;

//test for some defaults
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
if (nil == [prefs dictionaryRepresentation]["pref_sound"]) {
    playSound = YES;
    playVibrate = YES; 
} else {
    playSound = [prefs boolForKey:@"pref_sound"];
    playVibrate = [prefs boolForKey:@"pref_vibrate"]; 
}


if (playSound) {
    //do stuff
}

Hope this works for you.

Kevin Conner s solution works for me, but there s another thing I think I should point out.

My app has a preference for handedness with right-handed as the default. When I hit run in Xcode, use the app to change my preference to left-handed, and then run it a second time, my preference is still right-handed.

It seems that running in Xcode erases settings. I decided to manually quit the app from inside the simulator, open it again from inside, and then I saw my new preferences.





相关问题
Code sign Error

I have created a new iPhone application.I have two mach machines. I have created the certificate for running application in iPhone in one mac. Can I use the other mac for running the application in ...

ABPersonViewController Usage for displaying contact

Created a View based Project and added a contact to the AddressBook using ABAddressBookRef,ABRecordRef now i wanted to display the added contact ABPersonViewController is the method but how to use in ...

将音频Clips从Peter改为服务器

我不禁要问,那里是否有任何实例表明从Peit向服务器发送音响。 I m不关心电话或SIP风格的解决办法,只是一个简单的袖珍流程......

• 如何将搜查线重新定位?

我正试图把图像放在搜索条左边。 但是,问题始于这里,搜索条线不能重新布署。

热门标签