在将我的应用程序从v1升级到v2时,我对核心数据模型进行了一些小的更改。这些更改只是为模型添加新属性。
我使用之前和之后的更改对数据模型进行了版本化,并在我的App Delegate中实现了以下代码:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (__persistentStoreCoordinator != nil)
{
return __persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"ISDEmployees.sqlite"];
NSLog(@"storeURL:%@",storeURL);
NSError *error = nil;
// Create a dictionary for automatic lightweight core data migration
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
nil];
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
// Set up the persistent store and migrate if needed
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return __persistentStoreCoordinator;
}
基本上是标准的persistentStoreCoordinator,增加了迁移选项。此代码运行良好,我的数据库已成功更新。我遇到的问题是在数据库更新后,我需要刷新数据库中的所有数据,以便填充新列。我以为我会从相关实体/表中删除数据,并强制应用程序重新下载添加了列/属性的新数据集。
我不确定执行删除/更新的方式/位置。一般申请流程如下:
我知道我可以通过将此代码添加到persistentStoreCoordinator来检查是否需要迁移:
// Get the current data store meta data
BOOL migrationNeeded = NO;
NSDictionary *existingStoreData = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:storeURL error:&error];
if (existingStoreData)
{
// Check to see if new model is not the same as the existing mode, meaning a migration is required
if (![self.managedObjectModel isConfiguration:nil compatibleWithStoreMetadata:existingStoreData])
{
migrationNeeded = YES;
}
}
非常感谢任何帮助!!
更新#1:
根据以下反馈,我做了以下更改:
在AppDelegate上将migrationNeeded从本地变量更改为公共类变量。 在登录视图中,我添加了以下方法:
- (void)checkForDatabaseMigration
{
// Get a copy of the managed object context. If a migration is needed, it will kick it off
NSManagedObjectContext *managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
if ([(AppDelegate *)[[UIApplication sharedApplication] delegate] migrationNeeded])
{
// Delete all data from the table
}
managedObjectContext = nil;
}
这看起来是对的吗?代码工作,迁移后删除数据并插入新的副本。我只是讨厌在每次应用程序启动时检查迁移。
答案 0 :(得分:0)
如果您知道如何确定何时删除旧数据,您只需要获取所需的所有项目并将其删除。以下是您的操作方法(例如,如果您要删除所有 Man 设置):
NSFetchRequest * request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Man" inManagedObjectContext:myContext]];
[request setIncludesPropertyValues:NO]; //only fetch the managedObjectID
NSError * error = nil;
NSArray * men = [myContext executeFetchRequest:request error:&error];
//error handling goes here
for (NSManagedObject * man in men) {
[myContext deleteObject:man];
}
NSError *saveError = nil;
[myContext save:&saveError];
//more error handling here