Реализация «Автоматической облегченной миграции» для Core Data (iPhone) - PullRequest
49 голосов
/ 22 февраля 2010

Я бы хотел, чтобы мое приложение могло выполнять автоматическую облегченную миграцию при добавлении новые атрибуты в моей основной модели данных.

В руководстве от Apple это единственная информация по теме, которую я смог найти:

Автоматическая легкая миграция

по запросу автоматический легкий миграция, вы устанавливаете соответствующие флаги в словаре опций вы передаете в addPersistentStoreWithType: Конфигурация: URL: опции: ошибка :. Вам необходимо установить значения, соответствующие как NSMigratePersistentStoresAutomaticallyOption и NSInferMappingModelAutomaticallyOption ключи к ДА:

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.
}

Мой 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, чтобы работала Автоматическая облегченная миграция?

Ответы [ 5 ]

93 голосов
/ 22 февраля 2010

Это то, что я сделал для автоматической облегченной миграции (Источник: http://brainwashinc.wordpress.com/2010/01/18/iphone-coredata-automatic-light-migration/)

1. Задайте параметры постоянного хранилища для автоматической миграции в делегате приложения.

Измените свое создание persistentStoreCoordinator на это (замените 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;
}
7 голосов
/ 15 марта 2010

Сначала вышеуказанное решение не сработало для меня. Возвращенный managedObjectModel был 0x0. Я думаю, это потому, что я переименовал имена файлов различных файлов модели. Если вы будете следовать инструкциям выше к письму, то все это работает.

Однако, если вы измените имена файлов модели, вы можете выбрать «текущий» файл модели вручную: Допустим, исходный файл модели был MYMODEL.xcdatamodel после выполнения шага добавления модели выше это превращается в каталог MY.xcdatamodeld а под ним у вас есть MYMODEL.xcdatamodel и MYMODEL 2.xcdatamodel переименуйте новый файл модели в любое, что вы хотите, например, допустим, вы удалили пробел в MYMODEL2.xcdatamodel и измените его содержимое. Теперь в приведенном выше коде сделать

NSString *path = [mainBundle pathForResource:@"MYMODEL2" ofType:@"mom" inDirectory:@"MYMODEL.momd"];
1 голос
/ 09 октября 2013

Я думаю, что это добавляет к последнему ответу.

Поначалу использование ресурса комплекта и имен .sqlite показалось мне странным. Меняется ли имя ресурса пакета с изменением версии? Меняется ли имя .sqlite? Теперь моя миграция работает, и я узнал, что имя модели комплекта относится к имени каталога / папки в XCode, содержащей все модели, а не к названию версий модели в этом каталоге.

Когда вы даете имя ресурса модели:

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:modelResource withExtension:@"momd"];
NSManagedObjectModel *theManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

Это имя ресурса модели - это каталог / папка для моделей в 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 в папке / каталоге «Документы» (это , а не в комплекте).

Кроме того, при миграции с одной версии модели на другую версию модели имя файла .sqlite по умолчанию остается неизменным.

0 голосов
/ 16 ноября 2016

Решение Swift 3

1. Установите параметры постоянного хранилища для автоматической миграции в делегате приложения.

Измените ваше создание 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> Добавить версию модели - добавьте имя для новой модели

0 голосов
/ 13 декабря 2010

Оскар, в ответ на ваш вопрос я обнаружил то же самое изначально. Я бы предложил удалить и повторно добавить новый файл .xcdatamodeld в ваш проект, а затем перестроить. Надеюсь, это поможет!

...