PDA

View Full Version : Data persistence and app updates




nashyo
Feb 5, 2012, 01:59 AM
Hi,

I'm developing an app that requires a property list for the first time, and I'm a little confused about the file system and the conventions of using it. Especially, when future app versions are developed and the plist likely needs updating.

When my app opens, the plist should be installed so that it persists for the lifetime of the app version (i.e. until it is updated or uninstalled). I'd like to know any tips and tricks experienced developers may have for dealing with situations like this.

I suppose the logical development strategy goes like this:

When writing to sandbox directory
// search for directory and find path (append name of file, with extension, on path)
// if not found, create
// log any error

I found some code online that mentioned taking app versions into consideration, which makes a lot of sense if you intend to update your app in the future. But not all of the steps are clear to me and I'm hoping someone can help me understand the steps i'm unclear with.

// search for directory and instantiate NSUserDefaults ready for key/value retrieve of app version in next step
NSFileManager *defFM = [NSFileManager defaultManager];
NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) objectAtIndex:0];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

// statically declare current app version and retrieve older app version from NSUserDefaults, then compare. if appropriate, execute block.
// block sets app version, by assigning new key/value in NSUserDefaults.
// block continues to: find appDirectory and docDirectory? this i find confusing. Where should this data be saved?
//..Stuff that is done only once when installing a new version....
static NSString *AppVersionKey = @"MyAppVersion";
int lastVersion = [userDefaults integerForKey: AppVersionKey];
if( lastVersion != thisVersion ) //..do this only once after install..
{
[userDefaults setInteger: thisVersion forKey: AppVersionKey];
NSString *appDir = [[NSBundle mainBundle] resourcePath];
NSString *src = [appDir stringByAppendingPathComponent: @"xcodemade.plist"];
NSString *dest = [docsDir stringByAppendingPathComponent: @"xcodemade.plist"];
[defFM removeItemAtPath: dest error: NULL]; //..remove old copy
[defFM copyItemAtPath: src toPath: dest error: NULL];
}
//..end of stuff done only once when installing a new version.

Would anyone write this code differently, or does this cover it pretty well?



forum user
Feb 5, 2012, 06:39 AM
Would anyone write this code differently, or does this cover it pretty well?

Yes, write it differently. Do not think in "files containing preferences". Think in terms of the values and keys that make up the preference. Let NSUserPreferences do the persisting. Do not overwrite existing settings that the user has chosen.

Your migration strategy should be to add the new keys to the NSUserDefaults dictionary. Check the version stored in the NSUserPreferences: If version indicates that a certain setting is known then access the key. If version indicates a certain setting is unknown then add certain setting using defaults.

What ever you do, keep the users settings. User tend to get upset if an app deletes their settings during an update.

- Olaf