Question

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

Was it helpful?

Solution

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];
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top