Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSUserDefaults. setValue works, Not setBool

I trying to store some settings in NSUserDefaults, but It seems that the app won't store the setBool values.

This works:

[[NSUserDefaults standardUserDefaults] setValue: @"hello" forKey: @"test"]; [[NSUserDefaults standardUserDefaults] synchronize];

When I terminate the app and restart it, the value have been saved. However, when I do this:

[[NSUserDefaults standardUserDefaults] setBool: YES forKey: @"test"]; [[NSUserDefaults standardUserDefaults] synchronize]; It won't save after I close the app and restart it.

Should I file a bug report, or is there something I'm missing here?

Thanks

Edit:

I figure what I did wrong. In AppDelegate, I wanted to check if the boolForKey was set, and it it wasn't I did this:

if (![defaults boolForKey: @"test123"])
[defaults setBool: YES forKey: @"test123"];

... however, when it comes to boolWithKey, the "!" just check if the bool is YES or NO, not if its nil.

like image 306
BlackMouse Avatar asked Mar 06 '12 09:03

BlackMouse


People also ask

How does NSUserDefaults work?

NSUserDefaults caches the information to avoid having to open the user's defaults database each time you need a default value. When you set a default value, it's changed synchronously within your process, and asynchronously to persistent storage and other processes.

Where NSUserDefaults data is saved?

The user's defaults database is stored on disk as a property list or plist. A property list or plist is an XML file. At runtime, the UserDefaults class keeps the contents of the property list in memory to improve performance. Changes are made synchronously within the process of your application.

What is NSUserDefaults in swift?

A property list, or NSUserDefaults can store any type of object that can be converted to an NSData object. It would require any custom class to implement that capability, but if it does, that can be stored as an NSData. These are the only types that can be stored directly.


4 Answers

How can you be sure its not working? I tried your code and it works for me. Are you sure you are reading the Boolean in the correct way AFTER you write it?

This code SHOULD work:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:NO forKey:@"test"];

[defaults synchronize];

BOOL myBool = [defaults boolForKey:@"test"];
like image 109
Antonio MG Avatar answered Nov 08 '22 07:11

Antonio MG


I had the same problem by having the following code in my AppDelegate to keep track of whether the user had seen a particular viewController to display a walkthrough, and then setting this Bool to NO after the user had seen it.

if (![standardUserDefaults boolForKey:@"firstViewOfVC"]) {
        [standardUserDefaults setBool:YES forKey:@"firstViewOfVC"];
}

But then when you set it to NO later on and check if it "exists", you are actually seeing the NO boolean value and setting it back to yes. The quick fix is just to store the boolean value in an NSNumber object so that you can check for it's existence, independent of its value being YES or NO. See below:

if (![standardUserDefaults objectForKey:@"firstViewOfVC"]){
        [standardUserDefaults setValue:[NSNumber numberWithBool:YES] forKey:@"firstViewOfVC"];
    }
like image 38
DanWebster Avatar answered Nov 08 '22 07:11

DanWebster


I had the exact same problem. Everything EXCEPT BOOLs were persisting correctly; but i was using some old coding styles from ios 3. recoded this way, everything works.

If anybody else is using old books.... here is an example

Bad stuff:

//////////// set / get bL2R
if (![[NSUserDefaults standardUserDefaults]
      boolForKey:kL2RomanizationChoice]) {
    [[NSUserDefaults standardUserDefaults]
     setBool:YES
     forKey:kL2RomanizationChoice];
    bL2R = YES;
    NSLog(@"L2Rom not found, set to YES.");
}
else {
    bL2R   = [[NSUserDefaults standardUserDefaults]
              boolForKey:kL2RomanizationChoice];
    NSLog(@"L2Rom found.");
    if (bL2R) {
        NSLog(@"L2Rom found to be YES.");
    }

}

Good stuff:

if (![defaults boolForKey:kL2RomanizationChoice])
    [defaults setBool:YES forKey:kL1RomanizationChoice];

L2String_Setting = [defaults objectForKey:kSecondLangChoice];
bL2R = [defaults boolForKey:kL2RomanizationChoice];

Update: sadly this only seemed to work briefly, and now is failing again... using Xcode 4.5.2. may just swap out bools for integers...

like image 1
harry Avatar answered Nov 08 '22 08:11

harry


XCode 4.6 seems to have the same problem highlighted by hangzhouharry. A useful call is [[NSUserDefaults standardUserDefaults] dictionaryRepresentation] to see if your key values are looking the way they should.

For example -> autoLogout = 0;

which was set as a Bool, [settings boolForKey:@"autoLogout"] returns nothing

[settings integerForKey:@"autoLogout"] returns 0 (as, sort of, expected)

like image 1
arcady bob Avatar answered Nov 08 '22 08:11

arcady bob