views:

566

answers:

1

I want the user to be able to make some preferences like colors, prefered images, etc. When I use NSUserDefaults for this, on first start of the app there will be no preferences, right? So, every time I want to get a preference like

NSInteger avatarID = (NSInteger)[[NSUserDefaults standardUserDefaults] objectForKey:@"avatar"];

I have to check if it's null, and then use my system preference. But then I've seen this in the docs: +resetStandardUserDefaults

Are there two branches of defaults saved somewhere? The ones from the user, and the ones from the developer?

+2  A: 

Yes, but it's a little different than what you're doing. NSUserDefaults has the registerDefaults method, which lets you populate the "blank" defaults from an NSDictionary with values you provide. Put this in the +initialize method in your app controller, and you'll know the default values are sensible. If the user defaults object finds a "real" value for a key, either one you set during the current application launch or loaded from disk, it will always take precedent over what you provided in registerDefaults. resetStandardUserDefaults will remove the shared user defaults object from memory and undo any customization you've made to it, it's not something you'll need to provide default values.

Also, keep in mind you can't just cast an object to a primitive NSInteger value as you're doing, you'll just end up with a number representing the memory location of the object's pointer. Either use NSUserDefault's integerForKey: to get a primitive directly, or use objectForKey: to get an NSNumber and use integerValue to get the primitive value.

Marc Charbonneau
Cool. So in that NSDictionary I would put all my system defaults. When the user wants to change them, and I get the standardUserDefaults object, then an call to objectForKey:... would return the defaults of the user, and in case there are none for that key, it takes them from that dictionary? Or is it the other way?
Thanks
Essentially, yeah. NSUserDefaults will actually look through multiple search domains, including global system preferences, launch arguments and custom domains you specifically add. But for most cases you can think about it just like that, it will look for the user's settings, and return the value from the defaults dictionary if they don't exist.
Marc Charbonneau
You mean the +initialize method of the app delegate? Would that be the right place? Or could it also be in -applicationDidFinishLaunching?
Thanks
It doesn't really matter where you put it, but the +intitialize method is usually best because typically it's guaranteed to be called before other methods where you might need to access some of the defaults values.
Marc Charbonneau