我不知道保存 2 个数据库是否真的更好,因为您通常会更改不止一个以扩展功能。
对于数据库迁移,您可以使用类似的东西。
首先使用核心数据的内部版本控制系统,并将您当前使用的版本保存在NSUserDefaults 中,在我的示例中为infoDictionary(您连接的.plist 文件)。所以你可以先尝试轻量级的迁移,如果你的改动不能自动合并,可以试试manuel。
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
希望我能帮到你一点;)