Обновление модели Core Data iCloud со следующей версией приложения

#ios #core-data #migration #upgrade #icloud

#iOS #core-data #миграция #Обновление #icloud

Вопрос:

Мне нужно работать над следующей версией приложения, которое использует Core Data и iCloud. iCloud был активирован в текущей версии самым «современным» способом:

 if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                   configuration:@"data_cfg"
                                                             URL:storeURL
                                                         options:@{NSPersistentStoreUbiquitousContentNameKey:@"theStore"}
                                                           error:amp;error]) 
  

Теперь мне нужно обновить структуру хранилища, добавив новые объекты, отношения и так далее…

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

Какой наилучший способ выполнить подобное обновление? О чем я должен знать и на что мне следует обратить особое внимание? Как перенести текущие данные?

Ответ №1:

Обновление модели при использовании iCloud происходит так же, как и при отсутствии iCloud, за единственным исключением, что ваши изменения должны работать с автоматической упрощенной миграцией. В документации Apple подробно описаны требования к такого рода миграции. Основные шаги:

  1. Создайте новую версию модели данных и сделайте эту версию «текущей». (Вы должны сохранить старую модель, так что теперь у вас будет две, но только одна текущая).
  2. Внесите изменения в свою модель в новой версии.
  3. Добавьте NSMigratePersistentStoresAutomaticallyOption и NSInferMappingModelAutomaticallyOption в свой словарь параметров в приведенном выше коде, используя @YES в качестве значения для обоих.

Теперь, когда вы запускаете приложение, Core Data сравнивает старую и новую версии модели и (при условии, что ваши изменения работают для автоматической облегченной миграции) изменяет постоянное хранилище для использования новой версии.

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

Ответ №2:

Резервное копирование iCloud не имеет значения, кстати, вот решение для установки новой модели sqlite. Если данные внутри приложения можно воссоздать / загрузить с сервера, есть отличное решение. Вам не нужно настраивать стек миграции, есть очень быстрое решение. Хитрость заключается в удалении старой базы данных sqlite и создании новой.

Вот код, который я использовал при обновлении своего приложения. Вам нужно добавить это в свой AppDelegate.m

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
 NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"YourDatabase.sqlite"];
 NSManagedObjectModel *managedObjectModel = [self managedObjectModel];
 Ошибка NSError * ошибка = ноль;
 _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: managedObjectModel];

 // Проверьте, есть ли у нас уже постоянное хранилище
, если ( [[NSFileManager defaultManager] fileExistsAtPath: [storeURL path]] ) {
 NSDictionary * Существующее хранилище данных Metadata = [NSPersistentStoreCoordinator Метаданные forpersistentstoreoftype: NSSQLiteStoreType URL: storeURL ошибка: amp;ошибка];
 если ( !существующее хранилище данных) {
 // Что-то действительно плохое случилось с постоянным хранилищем
 // [Возникает исключение NSException: формат исключения NSInternalInconsistencyException: @"Не удалось прочитать метаданные для постоянного хранилища %@: %@", storeURL, ошибка];
 NSLog (@"Не удалось прочитать метаданные для постоянного хранилища %@: %@", storeURL, ошибка);
 }

 если ( ![managedObjectModel isConfiguration: nil compatibleWithStoreMetadata: существующий постоянный storemetadata] ) {
 если (![[NSFileManager defaultManager] removeItemAtURL: Ошибка storeURL: amp;ошибка] )
 NSLog (@"*** Не удалось удалить постоянное хранилище, %@", ошибка);
 } // иначе существующее постоянное хранилище совместимо с текущей моделью - отлично!
 } // еще нет файла базы данных

 [_persistentStoreCoordinator addPersistentStoreWithType:
Конфигурация NSSQLiteStoreType: nil
 URL:
Параметры storeURL:
ошибка nil:amp;ошибка];
 вернуть _persistentStoreCoordinator;
}

Этот код охватывает проблемы

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

Просто измените @»YourDatabase.sqlite» на ваше имя файла SQLiteDB, и все будет работать нормально.

Если ваши данные не могут быть воссозданы (синхронизированы с сервера), вам необходимо настроить стек миграции
, вот ссылка на руководство Apple https://developer.apple.com/library/mac/Documentation/Cocoa/Conceptual/CoreDataVersioning/CoreDataVersioning.pdf