views:

700

answers:

1

Hi there,

I've got a default settings plist file in the resources folder of my app, and on the first launch that gets copied to the documents folder.

In successive versions of the app, how can I merge the plist settings in their documents with any new keys & values (possibly nested) that have been added since the previous version?

I've seen a pattern where properties are actually created as an NSDictionary in the app (with all default settings), and then the current settings saved in the plist file is merged with that dictionary, and that is then saved over the current plist.

Is that a good approach? If so, how do you go about merging NSDictionary's that could have several nested values with sub arrays and sub dictionaries?

Also, is it advised to have a separate custom plist file for settings, or should you always use NSUserDefaults? Does NSUserDefaults handle versioning and changing defaults?

Many thanks,

Mike

+1  A: 

Okay I think I've come up with the best way to do it:

- (void)readSettings {

 // Get Paths
 NSString *defaultSettingsPath = [[NSBundle mainBundle] pathForResource:@"DefaultSettings" ofType:@"plist"];
 NSString *settingsPath = [self.applicationDocumentsPath stringByAppendingPathComponent:@"Settings.plist"];

 // Read in Default settings
 self.settings = [NSMutableDictionary dictionaryWithContentsOfFile:defaultSettingsPath];

 // Read in Current settings and merge
 NSDictionary *currentSettings = [NSDictionary dictionaryWithContentsOfFile:settingsPath];
 for (NSString *key in [currentSettings allKeys]) {
  if ([[self.settings allKeys] indexOfObject:key] != NSNotFound) {
   if (![[currentSettings objectForKey:key] isEqual:[self.settings objectForKey:key]]) {

    // Different so merge
    [self.settings setObject:[currentSettings objectForKey:key] forKey:key];

   }
  }
 }

}

- (void)saveSettings {
 if (self.settings) {
  NSString *settingsPath = [self.applicationDocumentsPath stringByAppendingPathComponent:@"Settings.plist"];
  [self.settings writeToFile:settingsPath atomically:YES];
 }
}
Michael Waterfall