Реализация “автоматической легкой миграции” для базовых данных (iPhone)

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

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

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

Для запроса автоматической легкой миграции Вы устанавливаете соответствующие флаги в словаре опций, который Вы передаете в addPersistentStoreWithType:configuration:URL:options:error:. Вам нужно к установленным значениям, соответствующим и 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 для получения Автоматической Легкой работы Миграции?

50
задан RickiG 22 February 2010 в 00:23
поделиться

2 ответа

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

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

Измените создание 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. Design -> Data Model -> Add Model Version (разверните элемент xcdatamodeld). Выберите файл "2″ (или более поздний), Design -> Data Model -> Set Current Version (отредактируйте эту версию)

3. Укажите ресурс momd в делегате app.

Измените реализацию 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;
}
93
ответ дан 7 November 2019 в 10:49
поделиться

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

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

NSString *path = [mainBundle pathForResource:@"MYMODEL2" ofType:@"mom" inDirectory:@"MYMODEL.momd"];
7
ответ дан 7 November 2019 в 10:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: