I don't know if it's really better to hold 2 databases, because you mostly change more than only the one to extend functionalities.
For database migration, you can use something like this.
First use the internal versioning system of the core-data and hold your currently used version in the NSUserDefaults
and in my example the infoDictionary
(your connected .plist file). So you can first try the lightweight migration and then the manuel if you changes cannot be automaticaly merged.
NSNumber *newDbVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"DBVersion"];
NSNumber *oldDbVersion = [[NSUserDefaults standardUserDefaults] objectForKey:@"DBVersion"];
NSURL *storeUrlOld;
if(!oldDbVersion)
storeUrlOld = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent:@"default.sqlite"]]; // default path
else
storeUrlOld = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: [NSString stringWithFormat:@"db_%d.sqlite",[oldDbVersion intValue]]]];
NSURL *storeUrlNew = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: [NSString stringWithFormat:@"db_%d.sqlite",[newDbVersion intValue]]]];
NSString *path = [[NSBundle mainBundle] pathForResource:@"myDB" ofType:@"momd"];
if(oldDbVersion)
path = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"db_%d.mom", [oldDbVersion intValue]]];
NSURL *momURLOld = [NSURL fileURLWithPath:path];
NSLog(@"mom-path old: %@", path);
NSLog(@"mom-url old: %@", momURLOld);
NSManagedObjectModel *oldManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURLOld];
// - - -
path = nil;
path = [[NSBundle mainBundle] pathForResource:@"db" ofType:@"momd"];
path = [path stringByAppendingPathComponent:[NSString stringWithFormat:@"db_%d.mom",[newDbVersion intValue]]];
NSURL *momURLNew = [NSURL fileURLWithPath:path];
NSLog(@"mom-path new: %@", path);
NSLog(@"mom-url new: %@", momURLNew);
NSManagedObjectModel *newManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURLNew];
// # # # # # # # # # # # # # # # # # # # # #
// - - - - Connect with old Database - - - -
// # # # # # # # # # # # # # # # # # # # # #
NSError *error;
NSPersistentStoreCoordinator *persistentStoreCoordinatorOld = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:oldManagedObjectModel];
// Allow inferred migration from the original version of the application.
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
if (![persistentStoreCoordinatorOld addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrlOld options:options error:&error])
{
// Handle the error
NSLog(@"Failed to add old persistent store: %@", [error localizedDescription]);
NSArray* detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
if(detailedErrors != nil && [detailedErrors count] > 0)
{
for(NSError* detailedError in detailedErrors) {
NSLog(@" DetailedError: %@", [detailedError userInfo]);
}
}
else
{
NSLog(@"ERROR persistentStoreCoordinator: %@", [error userInfo]);
}
return;
}
NSManagedObjectContext *oldManagedObjectContext = [[NSManagedObjectContext alloc] init];
[oldManagedObjectContext setPersistentStoreCoordinator:persistentStoreCoordinatorOld];
// # # # # # # # # # # # # # # # # # # # # #
// - - - - Connect with new Database - - - -
// # # # # # # # # # # # # # # # # # # # # #
NSPersistentStoreCoordinator *persistentStoreCoordinatorNew = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: newManagedObjectModel];
if (![persistentStoreCoordinatorNew addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrlNew options:options error:&error])
{
// Handle the error
NSLog(@"Failed to add new persistent store: %@", [error localizedDescription]);
NSArray* detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
if(detailedErrors != nil && [detailedErrors count] > 0)
{
for(NSError* detailedError in detailedErrors) {
NSLog(@" DetailedError: %@", [detailedError userInfo]);
}
}
else
{
NSLog(@"ERROR persistentStoreCoordinator: %@", [error userInfo]);
}
return;
}
NSManagedObjectContext *newManagedObjectContext = [[NSManagedObjectContext alloc] init];
[newManagedObjectContext setPersistentStoreCoordinator:persistentStoreCoordinatorNew];
managedObjectContext = newManagedObjectContext;
// # # # # # # # # # # # # # # # # # # # # # # #
// - - - Transfere data from old DB to new - - -
// # # # # # # # # # # # # # # # # # # # # # # #
// - - -
// # # # # # # # # #
// - - - Users - - -
// # # # # # # # # #
NSString *entityName = @"User";
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:oldManagedObjectContext];
[request setEntity:entity];
NSString *predicateFormat ;
NSPredicate *predicate;
error = nil;
NSMutableArray *mutableFetchResultsUsers = [NSMutableArray arrayWithArray: [oldManagedObjectContext executeFetchRequest:request error:&error]];
if (mutableFetchResultsUsers == nil) {
// Handle the error.
}
NSLog(@"Users: %@", mutableFetchResultsUsers);
for(User *user in mutableFetchResultsUsers)
{
NSLog(@"%@, %@, %@",user.userLogin,user.userDomain, user.serverAddress);
User *userNew = [[DatabaseFactory sharedInstance] newObject:@"User"];
[...] // do here integration
userNew.attibute = user.attribute;
[self saveContext];
}
[request release];
request = nil;
// next one
hope I could help you a bit ;)