#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 подробно описаны требования к такого рода миграции. Основные шаги:
- Создайте новую версию модели данных и сделайте эту версию «текущей». (Вы должны сохранить старую модель, так что теперь у вас будет две, но только одна текущая).
- Внесите изменения в свою модель в новой версии.
- Добавьте
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