Что мне нужно сделать, чтобы Core Data автоматически перенес модели? - PullRequest
95 голосов
/ 19 июня 2009

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

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

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

Ответы [ 10 ]

138 голосов
/ 19 июня 2009

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

В моем 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:

  1. Выберите файл xcdatamodel
  2. Выберите меню «Дизайн» вверху - затем Модель данных - затем выберите Добавить версию модели
  3. Ваш файл xcdatamodel будет перемещен в новый каталог с тем же именем, что и ваш файл xcdatamodel, но с расширением xcdatamodeld - в этом каталоге будет второй файл с 2 в имени. Выберите новый файл и затем Дизайн-> Модель данных-> Установить текущую версию ( в Xcode 4 вы делаете это )
  4. Если вы уже внесли изменения, которые привели к несовместимости проекта, удалите эти изменения из исходного файла xcdatamodel. Если вам еще предстоит внести изменения - просто отредактируйте файл 2.xcdatamodel (тот, который вы только что сделали в текущей версии).
  5. Теперь, когда вы устанавливаете эту версию на устройство, которое имеет старую модель - оно автоматически обновит эту модель до новой модели.

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

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


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

Спасибо @ rockstarberlin за указание на обновленную документацию на apple:

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

Обновление: 19.08.2013, лучшая ссылка:

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

13 голосов
/ 03 августа 2009

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

6 голосов
/ 01 июля 2010

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

основные проблемы с миграцией данных

3 голосов
/ 16 февраля 2011

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

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

1 голос
/ 02 июня 2013

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

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

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

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

1 голос
/ 03 января 2012

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

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

1 голос
/ 14 июля 2011

меню в Xcode 4 немного изменилось. Вот описание, как это сделать в Xcode 4:

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

1 голос
/ 31 января 2011

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

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

Если ваш файл модели называется «Модель», то вот как вы создаете управляемую модель объекта:

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

Благодарим от этого блога .

0 голосов
/ 18 октября 2013

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

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

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

0 голосов
/ 29 марта 2013

iOS 4.0 +

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"model" withExtension:@"momd"];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...