Реализация "Автоматическая легкая миграция" для основных данных (iPhone)
Я хочу, чтобы мое приложение смогло сделать автоматическую легкую миграцию, когда добавляю
новые атрибуты моей основной модели данных.
В руководстве от Apple это единственная информация по этому вопросу, которую я мог найти:
Автоматическая легкая миграция
Чтобы запросить автоматический легкий вес миграции, вы устанавливаете соответствующие флаги в словаре опций, которые вы передаете addPersistentStoreWithType: Конфигурация: URL: опции: ошибка:. Вам нужно установить соответствующие значения как для NSMigratePersistentStoresAutomaticallyOption и NSInferMappingModelAutomaticallyOption клавиши YES:
NSError *error;
NSURL *storeURL = <#The URL of a persistent store#>;
NSPersistentStoreCoordinator *psc = <#The coordinator#>;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
if (![psc addPersistentStoreWithType:<#Store type#>
configuration:<#Configuration or nil#> URL:storeURL
options:options error:&error]) {
// Handle the error.
}
My NSPersistentStoreCoordinator
инициализируется следующим образом:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"FC.sqlite"]];
NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return persistentStoreCoordinator;
}
У меня возникли проблемы с тем, как и как я должен добавить код Apple для работы автоматической облегченной миграции?
Ответы
Ответ 1
Это то, что я сделал, чтобы сделать автоматическую легкую миграцию (Источник: http://brainwashinc.wordpress.com/2010/01/18/iphone-coredata-automatic-light-migration/)
1. Установите параметры Persistent Store для автоматической миграции в делегате приложения.
Измените ваше постоянное созданиеStoreCoordinator на это (замените YOURDB):
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"YOURDB.sqlite"]];
// handle db upgrade
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
// Handle error
}
return persistentStoreCoordinator;
}
2. Верните свою модель данных и отредактируйте новый файл.
Выберите файл xcdatamodel
Дизайн → Модель данных → Добавить версию модели (разверните элемент xcdatamodeld)
Выберите "2" (или более поздний) файл, "Дизайн" → "Модель данных" → "Установить текущую версию" (отредактируйте эту версию).
3. Укажите ресурс momd в делегате приложения.
Измените реализацию managedObjectModel на это (замените YOURDB)
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
NSString *path = [[NSBundle mainBundle] pathForResource:@"YOURDB" ofType:@"momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];
return managedObjectModel;
}
Ответ 2
Сначала это решение не сработало для меня. Возвращаемая команда managedObjectModel была 0x0.
Я думаю, это связано с тем, что я переименовал имена файлов в разных файлах модели.
Если вы следуете приведенным выше инструкциям в письме, все это работает.
Однако, если вы измените имена файлов моделей, вы можете вручную выбрать "текущий" файл модели:
Допустим, ваш оригинальный файл модели был MYMODEL.xcdatamodel
после того, как шаг добавления модели выше, он превращается в каталог MY.xcdatamodeld
и под ним у вас есть MYMODEL.xcdatamodel и MYMODEL 2.xcdatamodel
переименуйте новый файл модели во все, что вы хотите, например, скажем, вы удалили пространство в MYMODEL2.xcdatamodel и отредактировали его содержимое.
Теперь в приведенном выше коде do
NSString *path = [mainBundle pathForResource:@"MYMODEL2" ofType:@"mom" inDirectory:@"MYMODEL.momd"];
Ответ 3
Я думаю, что это добавляет последний ответ.
Я обнаружил, что использование ресурса пакета и имена .sqlite действительно запутывают сначала. Изменяется ли имя ресурса узла с изменением версии? Изменено ли имя .sqlite? Теперь у меня появилась моя миграция, и узнал, что имя модели связки относится к имени каталога/папки в XCode, содержащем все модели, а не имени версий модели в этом каталоге.
Когда вы даете имя моделиResource для:
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:modelResource withExtension:@"momd"];
NSManagedObjectModel *theManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
Это имя моделиResource является каталогом/папкой для моделей в Xcode.
Когда вы выполните:
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:storeFileName];
NSError *error = nil;
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
// handle error
}
StoreFileName - это имя вашего файла .sqlite в папке Documents/directory (это не в комплекте).
Кроме того, при переходе с одной версии модели на другую версию модели по умолчанию имя файла .sqlite остается неизменным.
Ответ 4
Оскар, в ответ на вашу проблему, я нашел то же самое сначала. Я бы предложил удалить и повторно добавить новый файл .xcdatamodeld в ваш проект, а затем перестроить. Надеюсь, это поможет!
Ответ 5
Решение Swift 3
1. Установите параметры Persistent Store для автоматической миграции в делегате приложения.
Измените ваше создание persistentStoreCoordinator на это (замените SingleViewCoreData.sqlite):
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
let coordinator: NSPersistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.appendingPathComponent("SingleViewCoreData.sqlite")
let options = [
NSMigratePersistentStoresAutomaticallyOption : Int(true),
NSInferMappingModelAutomaticallyOption : Int(true)
]
do {
try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: options)
} catch {
print(error)
}
return coordinator
}()
2. Верните свою модель данных и отредактируйте новый файл.
Выберите файл xcdatamodel Редактор файлов > Добавить версию модели - добавьте имя для новой модели