What is the use of -[NSUserDefaults registerDefaults:]?

IphoneCocoa TouchNsuserdefaults

Iphone Problem Overview


What is the difference between:

[[NSUserDefaults standardUserDefaults] registerDefaults:
  [NSDictionary dictionaryWithObjectAndKey:anObject, @"something"]];

And this:

[[NSUserDefaults standardUserDefaults] setObject:anObject forKey:@"something"];

Iphone Solutions


Solution 1 - Iphone

The difference is that the first code-snippet you register defaults that will be used when the user has not made any changes to the "property".

So if you want to provide let's say a "property" with the key name 'Welcome message', you could instead of having the property returning nil insert a default message 'Welcome first-time user' that will be displayed when there have been no changes to the property.

This will simplify your logic because you don't need to write an if test to check if the "property" returns nil and then make another message if this is the case.

NSString *greeting = [[NSUserDefaults standardUserDefaults] stringForKey:@"Greeting"];

if(greeting == nil) {
    NSLog(@"Welcome first-time user!");
}

The second code-snippet you posted is for setting the property to another value. You will have different set methods (setString, setObject, setBoolean) to set values depending on your program state in the Userdefaults.

EDIT-----Updates as requested in comment.

The first method is for registering values to defaults, as the name implies. The first time you access the property with some key name the value will be either nil for objects, false for booleans or 0 for numbers. Instead of doing a lot of tests and so on to so if the values is not set in the program, and then do something "default" action such as the example above, you can ship your application with some already predefined values for these keys.

A typical place to put the registerDefaults is in the initializer-method in the appDelegate.

Then somewhere in your program you may want to set the values of these fields then you use the setObject, setString, setBoolean...and for retrieving you use stringForKey, objectForKey...

Think of it as this

The registerDefaults is the constructor where you may supply sensible values for the object, otherwise you get some defaults which I already wrote. Then later if you want to change the object's attributes you do NOT use the "constructor" but the set/get methods.

Solution 2 - Iphone

Long story short,

[[NSUserDefaults standardUserDefaults] setObject:@"Entropy" forKey:@"kName"]

will save "Entropy" to a file named com.example.Demo.plist in Library/Preference folder (where com.example.Demo is your Bundle ID, see IOS Application Security Part 20 – Local Data Storage)

[[NSUserDefaults standardUserDefaults] setObject:@"Mac OS X" forKey:@"kOS"];
NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
                                @"Windows", @"kOS",
                                @"Google", @"kSearchEngine", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];

NSLog(@"%@", [[NSUserDefaults standardUserDefaults] objectForKey:@"kOS"]);
NSLog(@"%@", [[NSUserDefaults standardUserDefaults] objectForKey:@"kSearchEngine"]);
NSLog(@"%@", [[NSUserDefaults standardUserDefaults] objectForKey:@"kBrowser"]);

will print "Mac OS X", "Google", (null)

In fact, registerDefaults

> - does not save to disk > - only sets value for keys that haven't been set ("kOS" is set by setObject:forKey: and "kSearchEngine" is not set) > - returns 0 for scalar values, nil for objects if that key is not set by both registerDefaults and setObject:forKey: ("kBrowser" in this case)

And the usage of registerDefaults

Quoted from Preferences and Settings Programming Guide

> If these standard default values are not appropriate for your app, you > can register your own default values using the registerDefaults: > method. This method places your custom default values in the > NSRegistrationDomain domain, which causes them to be returned when a > preference is not explicitly set.

Quoted from How to Save Data with NSUserDefaults

> Another tip is that you can initialize your NSUserDefaults with a > pre-defined NSDictionary object. So for example you could set a > default value to be “false” or “true” before the user ever had a > chance to interact with your program. In my case, sometimes I create > an array that represents all the levels in my game, and in each array > value I store a boolean to check if a player has finished the level. > To do this I create the data object and then register it with > NSUserDefaults. If a previous value exists for the object, then > nothing happens. Otherwise my blank object gets saved as the “default” > defaults

PS: Ole has a very good article explaining Handling Default Values With NSUserDefaults in detail

Solution 3 - Iphone

Another way of looking at it is this. If you delete the preferences file from ~/Library/Preferences, the defaults that are set by registerDefaults will be the ones that apply to the application until new preferences are set.

Solution 4 - Iphone

In Swift 2.1.1 Xcode 7.2

I added this snippet to application:didFinishLaunchingWithOptions to initialise the tintColorsIndex which is one of parameters user can change in the app.

    let defaults = NSUserDefaults.standardUserDefaults()
    defaults.registerDefaults([
        "tintColorsIndex" : -1,
        ])

When the app is launched the very first time the tintColorsIndex will be assigned a value of -1 (an Int). If user has changed the color while using the app, their preference won't be overridden at subsequent launches.

Solution 5 - Iphone

User Defaults are grouped in domains... registerDefaults is used to add defaults to the registration domain..

You can read about the domains in Preferences and Settings Programming Guide.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEnrico SusatyoView Question on Stackoverflow
Solution 1 - IphoneLuckyLukeView Answer on Stackoverflow
Solution 2 - Iphoneonmyway133View Answer on Stackoverflow
Solution 3 - IphoneAbizernView Answer on Stackoverflow
Solution 4 - IphoneJervisbayView Answer on Stackoverflow
Solution 5 - IphoneSwapnil LuktukeView Answer on Stackoverflow