Что мне нужно сделать, чтобы заставить Core Data автоматически переносить модели?

Я прочитал документацию об автоматической/облегченной миграции для моделей Core Data - но у меня возникли проблемы с ее реализацией.

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

Любые указатели - мне нужно установить что-то в Xcode?

Ответ 1

Теперь я узнал, что это довольно просто - как только вы знаете, где искать.

В моем приложении AppDelegate я настроил NSPersistentStoreCoordinator - и вам нужно добавить некоторые опции для этого, чтобы сказать, что он обрабатывает автоматическую миграцию:

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:

[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,

[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

NSError *error;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];

if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
    // Handle error
    NSLog(@"Problem with PersistentStoreCoordinator: %@",error);
}

Затем вам нужно сделать небольшой трюк в xCode:

  • Выберите файл xcdatamodel
  • Выберите меню "Дизайн" вверху - затем "Модель данных", затем выберите "Добавить версию модели"
  • Затем ваш файл xcdatamodel переместится в новый каталог с тем же именем, что и файл xcdatamodel, но с расширением xcdatamodeld - в этом каталоге будет второй файл с именем 2. Выберите новый файл, а затем Design- > Data Model- > Set Current Version (в Xcode 4 вы сделаете это)
  • Если вы уже внесли изменения, которые привели к несовместимости вашего проекта, внесите эти изменения из исходного файла xcdatamodel. Если вам еще нужно внести изменения, просто измените файл 2.xcdatamodel(тот, который вы только что сделали текущей версией).
  • Теперь, когда вы устанавливаете эту версию на устройство с старой моделью, оно автоматически обновит эту модель до новой модели.

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

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


ОБНОВЛЕНИЕ (15/07/2011):

Благодаря @rockstarberlin за то, что в яблоке есть обновленная документация:

Xcode 4: установка моделей управляемых объектов Текущая версия

Обновление: 8/19/2013 лучшая ссылка:

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/vmModelFormat.html

Ответ 2

Это было невероятно полезно. Документация Apple была, как обычно, крайне неполной. Я рекомендую делать чистую сборку, так как я столкнулся с ошибкой "Не могу объединить модели с двумя разными объектами xxx", когда я впервые запускал после внесения этих изменений. Чистая сборка зафиксировала его.

Ответ 3

Решение Grouchal идеально подходит, но если у вас все еще есть "Невозможно объединить модели с двумя разными объектами xxx" даже после очистки сборки несколько раз... Возможно, у вас могут быть проблемы с тем, как управляется управляемый объектObjectModel загрузился... возьмите взгляд на этот..., который помог мне исправить это.

проблемы переноса основных данных

Ответ 4

Кроме того, если вы наткнулись на этот пост, как и я, после получения "Модель, используемая для открытия магазина, несовместима с ошибкой, используемой для создания хранилища", и вы просто отлаживаете с помощью симулятора и хотите полностью замените установленную старую модель, вы можете просто Reset приложение Simulator или удаление вашего приложения из симулятора, вероятно, тоже будет работать.

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

Ответ 5

Чтобы ответить на ответ Santthosh, подумал, что я разместил здесь фрагмент кода. Вам нужно создать свой управляемый объект с помощью initWithContentsOfURL: вместо mergedModelFromBundles:, иначе вы получите сообщение об ошибке:

Невозможно объединить модели с двумя разными объекты XXX и XXX

Если ваш файл модели назван "Модель", здесь вы создаете файл managedObjectModel:

NSString *path = [[NSBundle mainBundle] pathForResource:@"Model" ofType:@"momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL]; 

Кредит этот пост в блоге.

Ответ 7

У меня была эта проблема в течение многих лет, и я пробовал все эти ответы безрезультатно. Сегодня я наконец понял, что я делаю неправильно. Очень простая проблема, но я ее не замечал. При создании более новой версии модели данных, если вы используете столбцы ADDING, обязательно указывайте их как ДОПОЛНИТЕЛЬНЫЕ. Если вы не выполните простую миграцию, это не сработает, потому что новые значения столбца не будут заполнены.

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

Ответ 8

Я наткнулся на этот пост из-за других проблем, но ошибка была " Конфигурация модели, используемая для открытия хранилища, несовместима с той, которая использовалась для создания хранилища."

Вот моя проблема и решение. В моей модели я использовал конфигурации. У меня было несколько объектов, которые хранятся в одном файле, а остальные - во втором файле. (У меня есть некоторые значения по умолчанию, которые могут периодически потребоваться для загрузки, и было бы невероятной болью, чтобы объединить их в целом). Во всяком случае, я создал новую сущность. Программа, казалось, работала нормально, но всякий раз, когда я уходил, у меня была ошибка выше.

Решение заключалось в том, чтобы посмотреть на мои конфигурации, понять, что у меня есть объект, который в настоящее время не находится ни в одной из конфигураций, и добавьте его в один. Бегает как сон.

Это не устранит проблему OP. Но, возможно, какой-то разочарованный человек, который приземляется здесь через google, будет в лодке, в которой я был:)

Ответ 9

iOS 4.0 +

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

Ответ 10

Незначительное редактирование для @Grouchal удивительных инструкций выше для Xcode версии 5:

Старый: 2. Выберите меню "Дизайн" вверху - затем "Модель данных", затем выберите "Добавить версию модели"

Версия 5+: 2. Выберите меню "Редактор", затем "Добавить версию модели...", введите название своей версии и на основе модели (выберите свою оригинальную модель из списка)