NSUserDefaults are not present on first run on the simulator

I have some settings saved in my Settings.bundle, and I try to use them in application:didFinishLaunchingWithOptions , but when I first run on a simulator that accesses objects by key, nil always returned (or 0 in the case of ints). As soon as I go to the settings screen and exit, they will work fine for each launch after that.

What's happening? Does it make sense to use the default values ​​in the Settings.bundle file to be able to use them without requiring the user to enter them first?

+4
source share
4 answers

If I asked the question correctly, in the app app delegate - (void) applicationDidFinishLaunching: (UIApplication *) set the default values ​​for my settings by calling registerDefaults: dictionaryWithYourDefaultValues ​​in [NSUserDefaults standardUserDefaults]

 - (void)applicationDidFinishLaunching:(UIApplication *)application { NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt:3], @"SomeSettingKey", @"Some string value", @"SomeOtherSettingKey", nil]; [ud registerDefaults:dict]; } 

These values ​​will only be used if these settings have not been set or changed by previous versions of your application.

+5
source

As the saying goes, "you must determine if this is the first download, and then first save all your default values."

In the DidFinishLaunching app, try to set the default value in your preferences.

Here is an example:

 NSUserDefaults *defaults =[NSUserDefaults standardUserDefaults]; if([defaults objectForKey:@"YOUR_KEY"] == nil) { [defaults setValue:@"KEY_VALUE" forKey:@"YOUR_KEY"]; } 

When the application starts a second time, it will have KEY_VALUE for YOUR_KEY.

Thanks,
Jim.

+3
source

Does it make sense to use the default settings in the Settings.bundle parameter can use them without requiring you to enter them first?

Not. The point of the preset is to provide the user with a place to edit all the settings of third-party applications in a convenient place. Regardless of whether this centralization is really a good idea, it is a user experience problem that is off topic.

In order to answer your question, you must determine if this is the first download, and then first save all your default values.

And while we are on this issue, I also checked “In-app bundle” as it provides your app with an easy way to display your app’s settings in both places (in the app and Settings.app) with minimal code.

+2
source

The values ​​in the Settings.bundle file are for the settings application, which can populate the default values ​​for your application. They are not used by your own application. But you can set the default settings yourself using the registerDefaults: NSUserDefaults method. This does not actually install them to disk, but simply gives "default values ​​for default values": they are used when the user has not yet set the value.

RegisterDefaults setting: must be done before using default values. The "applicationDidFinishLaunching:" method that others have suggested for this is too late in most cases. By the time you call "applicationDidFinishLaunching:" your views are already loaded from nib files, and their "viewDidLoad:" methods have been called. And they can usually read custom defaults.

To ensure that the default settings are set before first use, I use the following utility class, which loads the values ​​from the Root.plist file and sets them using "registerDefaults:". This class is used to read custom defaults instead of "[NSUserDefaults standardUserDefaults]". Instead, use "[Receive Settings]".

As a bonus, it also contains a method for registering default change notifications for the user, since I always forget how this is done.

 #import "Settings.h" @implementation Settings static bool initialized = NO; + (void) setDefaults { NSString *bundlePath = [[NSBundle mainBundle] bundlePath]; NSString *settingsBundlePath = [bundlePath stringByAppendingPathComponent:@"Settings.bundle"]; NSBundle *settingsBundle = [NSBundle bundleWithPath:settingsBundlePath]; NSString *settingsPath = [settingsBundle pathForResource:@"Root" ofType:@"plist"]; NSDictionary *settingsDict = [NSDictionary dictionaryWithContentsOfFile:settingsPath]; NSArray *prefSpecifierArray = [settingsDict objectForKey:@"PreferenceSpecifiers"]; NSMutableDictionary *appDefaults = [[NSMutableDictionary alloc] init]; for (NSDictionary *prefItem in prefSpecifierArray) { NSString *key = [prefItem objectForKey:@"Key"]; if (key != nil) { id defaultValue = [prefItem objectForKey:@"DefaultValue"]; [appDefaults setObject:defaultValue forKey:key]; } } // set them in the standard user defaults [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults]; if (![[NSUserDefaults standardUserDefaults] synchronize]) { NSLog(@"Settings setDefaults: Unsuccessful in writing the default settings"); } } + (NSUserDefaults *)get { if (!initialized) { [Settings setDefaults]; initialized = YES; } return [NSUserDefaults standardUserDefaults]; } + (void) registerForChange:(id)observer selector:(SEL)method { [[NSNotificationCenter defaultCenter] addObserver:observer selector:method name:NSUserDefaultsDidChangeNotification object:nil]; } + (void) unregisterForChange:(id)observer { [[NSNotificationCenter defaultCenter] removeObserver:observer name:NSUserDefaultsDidChangeNotification object:nil]; } 
+2
source

Source: https://habr.com/ru/post/1309175/


All Articles