Pitfall in using default values in settings bundle

Published on August 1, 2010

If you are implementing application settings using iPhone’s Application Preferences, then you will want to take note of this pitfall.

Referring to the schema reference for PSTextFieldSpecifier, you would notice that there is a DefaultValue key. You might thought that this key is to return a default value, when the preference is not set.

In terms of code, you might thought that myvalue would return the default value.</p>

NSString *myvalue = [[NSUserDefaults standardUserDefaults] stringForKey:@"mykey"]

</p>

But no, that is NOT the case. myvalue will always return nil, until you go to the Application Preferences page. In order to read a default value correctly, you will have to do more.

Refer to AppPrefs Sample Code on how that can be done. The code is copied here for reference.

 NSString *testValue = [[NSUserDefaults standardUserDefaults] stringForKey:kFirstNameKey];
 if (testValue == nil)
 {
   // no default values have been set, create them here based on what's in our Settings bundle info
   NSString *pathStr = [[NSBundle mainBundle] bundlePath];
   NSString *settingsBundlePath = [pathStr stringByAppendingPathComponent:@"Settings.bundle"];
   NSString *finalPath = [settingsBundlePath stringByAppendingPathComponent:@"Root.plist"];
    NSDictionary *settingsDict = [NSDictionary dictionaryWithContentsOfFile:finalPath];
   NSArray *prefSpecifierArray = [settingsDict objectForKey:@"PreferenceSpecifiers"];
 
    NSString *firstNameDefault;
 
    NSDictionary *prefItem;
   for (prefItem in prefSpecifierArray)
    {
     NSString *keyValueStr = [prefItem objectForKey:@"Key"];
     id defaultValue = [prefItem objectForKey:@"DefaultValue"];
 
      if ([keyValueStr isEqualToString:kFirstNameKey])
      {
       firstNameDefault = defaultValue;
      }
     // Handle for other preferences you might have
      // ...
    }
 
   // since no default values have been set (i.e. no preferences file created), create it here   
    NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
                   firstNameDefault, kFirstNameKey,
                    nil];
   [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
   [[NSUserDefaults standardUserDefaults] synchronize];
  }
 
  // we're ready to do, so lastly set the key preference values
  firstName = [[NSUserDefaults standardUserDefaults] stringForKey:kFirstNameKey];