简短的问题:
我想在我的核心数据模型发生变化(新实体,新属性等)时在我的应用程序中运行某些代码。如何确定模型是否已更改?
只是一些伪代码:
if (current_model_version != previous_model_version) {
//do some code
} else {
// do some other code
}
我猜我可能会使用versionHashes来执行此操作,或者isConfiguration:compatibleWithStoreMetadata:,但我不确定如何。
为了清晰起见,进行了一些编辑:“当前”和“上一次”中的“当前”一样,“上一次应用程序已启动”。
答案 0 :(得分:9)
答案似乎是 isConfiguration:compatibleWithStoreMedia:。
我在这里找到了一些有用的信息:
http://mipostel.com/index.php/home/70-core-data-migration-standard-migration-part-2
我这样设置:
- (BOOL)modelChanged
{
NSError *error;
NSURL * sourceURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"db.sqlite"];
NSDictionary *sourceMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:sourceURL error:&error];
BOOL isCompatible = [[self managedObjectModel] isConfiguration:nil compatibleWithStoreMetadata:sourceMetadata];
return isCompatible;
}
'self'是我的共享数据存储,而不是必须去那里。
deanWombourne指出,这真正做的是确定数据是否可以自动迁移,因此它并不是我提出的问题的解决方案。在这种情况下,它确实满足了我的需求。
答案 1 :(得分:1)
如果您在XCode中设置新项目时勾选Core Data框,则会获得- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
的替换代码。
它尝试打开现有的sqlite文件(如果需要,使用轻量级迁移)。如果失败,则删除并重新创建商店。
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
return _persistentStoreCoordinator;
}
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSError *error = nil;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:self.storeURL options:options error:&error])
{
NSLog(@"Couldn't open the store. error %@, %@", error, [error userInfo]);
[self deleteSqliteFilesForStore:self.storeURL];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:self.storeURL options:options error:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
// or [NSException raise ...]
}
else
{
NSLog(@"Store deleted and recreated");
// TEST DATA RE-INITIALIZATION CODE GOES HERE
}
}
else
{
NSLog(@"Existing Store opened successfully");
}
return _persistentStoreCoordinator;
}
- (void)deleteSqliteFilesForStore:(NSURL *)storeURL
{
NSURL *baseURL = [storeURL URLByDeletingPathExtension];
// Delete the associated files as well as the sqlite file
for (NSString *pathExtension in @[@"sqlite",@"sqlite-shm",@"sqlite-wal"])
{
NSURL *componentURL = [baseURL URLByAppendingPathExtension:pathExtension];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:[componentURL path]];
if(fileExists)
{
[[NSFileManager defaultManager] removeItemAtPath:[componentURL path] error:nil];
}
}
}