Определение появления новых версий в базовой модели данных
Краткий вопрос:
Я хочу запустить определенный код в моем приложении, только если изменилась моя модель базовых данных (новые сущности, новые свойства и т. Д.). Как я могу определить, изменилась ли модель или нет?
Просто псевдокод:
if (current_model_version != previous_model_version) {
//do some code
} else {
// do some other code
}
Я предполагаю, что я мог бы использовать versionHashes, чтобы сделать это, или isConfiguration: compatibilityWithStoreMetadata:, но я не уверен, как.
Некоторые изменения для ясности: "текущий", как в "сейчас", и "предыдущий", как в "последний раз приложение запускалось".
2 ответа
Ответ, кажется, isConfiguration:compatibilityWithStoreMedia:.
Я нашел некоторую полезную информацию здесь:
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;
}
"Я" - это мое общее хранилище данных, но оно не обязательно должно быть там.
deanWombourne указывает, что это действительно определяет, могут ли данные быть автоматически перенесены, так что это не совсем решение проблемы, которую я поставил. Это действительно служит моим потребностям в этом случае.
Это код замены для - (NSPersistentStoreCoordinator *)persistentStoreCoordinator
что вы получите, если вы установите флажок Core Data при настройке нового проекта в XCode.
Он пытается открыть существующий файл 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];
}
}
}