NSUserDefaults cannot stop application launch / startup
EDIT: Code updated to reflect Paul.s.
Been browsing SO last week and still can't get my app to save settings changes from app to shutdown / restart app in Sim and on device.
Trying to use NSMutableDictionary from Singleton, but I don't think this is the problem.
a) Set initial default values for the application using registerDefaults in the AppDelegate applicationDidFinishLaunchingWithOptions:
AppManager *global = [AppManager sharedInstance];
// set up the defaults.
global.gWantFoo = YES; // This is a BOOL which relates to a UISwitch
// #define kWantFoo @"gWantFoo"
global.globalSettingsDict = [[NSMutableDictionary alloc]
initWithObjectsAndKeys:
[NSNumber numberWithBool:global.gWantFoo], kWantFoo, nil];
global.globalSettings = [NSUserDefaults standardUserDefaults];
[global.globalSettings registerDefaults:global.globalSettingsDict];
[global.globalSettings synchronize];
b) In ConfigView, where I can set a switch, I have a selector doing the following when changing a switch.
self.global.gWantFoo = NOT(self.global.gWantFoo); // #define NOT(a) !(a)
[self.global.globalSettings setBool:self.global.gWantFoo forKey:kWantFoo];
[self.global.globalSettings synchronize];
c) I have a sync on applicationDidEnterBackground and friends, and although the switch value persists for the lifetime of the application, after a reboot, gWantFoo is overwritten by default "YES".
Any advice is appreciated. I am on the verge of defending my ailing macbook pro with a barrage of curses by following him closely. Ok, I settled down for this edit. I feel myself gently shaking my macbook pro to demonstrate that I am less than happy with NSUserDefaults :-)
Greetings
Sc.
source to share
So from start to finish this is what you have to do / what has to happen
In application:didFinishLaunchingWithOptions:
one of the first things you do - it is the default value, such as:
NSDictionary *defaultsDefaults = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithBool:NO] , PSWantFoo, nil];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults registerDefaults:defaultsDefaults];
Note: PSWantFoo
defined as NSString * const PSWantFoo = @"PSWantFoo";
, so I don't have string literals littered all over the place.
At this point, if the application has never started NSLog(@"%d", [defaults boolForKey:PSWantFoo]);
, it will print 0
.
Now when I want to set a value, I use something like:
[defaults setBool:YES forKey:PSWantFoo];
[defaults synchronize];
Now when I run NSLog(@"%d", [defaults boolForKey:PSWantFoo]);
it will print 1
.
As for the persistence at this point, since I actually set the value, then a plc layer is created for me
<path to app>/Library/Preferences/<bundle identifier>.plist
If you check this file, you will see something like
<?xml version="1.0" encoding="UTF-8"?>
<DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PSWantFoo</key>
<true/>
</dict>
</plist>
Now from this point this value will be read in contrast to the one registered in registerDefaults:
Update
Why did you enter this code in this order?
// set up the defaults.
global.gWantFoo = YES; // This is a BOOL which relates to a UISwitch
Why not do it the other way around?
Register defaults with default YES;
NSDictionary *defaultsDefaults = [[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithBool:YES], kWantFoo, nil];
[defaults registerDefaults:defaultsDefaults];
and then after that you get the setting
global.gWantFoo = [defaults boolForKey:kWantFoo];
So, if the app hasn't set a preference yet, the answer will be YES
, otherwise it will be what the app previously set it to.
source to share