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

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

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

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


person Grouchal    schedule 19.06.2009    source источник


Ответы (10)


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

В моем 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 в имени. Выберите новый файл, а затем Design-> Data Model-> Set Current Version (в 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

person Grouchal    schedule 19.06.2009
comment
Я предлагаю прочитать Руководство по миграции и управлению версиями основных данных, доступное в программе просмотра документов Xcode и на сайте developer.apple.com. - person Hunter; 19.06.2009
comment
Я не нашел там простого ответа - потребовалось время, чтобы понять, как это сделать. - person Grouchal; 19.06.2009
comment
NSInferMappingModelAutomaticallyOption работает хорошо, но только для простых сопоставлений, таких как изменение имени атрибута. Для чего-то более сложного (отношения, удаление или добавление сущностей) вам нужно будет добавить модель сопоставления. Если Xcode жалуется, что NSInferMappingModelAutomaticallyOption не объявлен, добавьте #import ‹CoreData / CoreData.h› в файл заголовка делегата вашего приложения. - person Elise van Looij; 29.09.2009
comment
Я добавил несколько сущностей в свою модель и получил печально известную модель, которая использовалась для открытия магазина, несовместима с той, которая использовалась для создания ошибки магазина. Ваше решение исправило это! Большое тебе спасибо! - person Karsten Silz; 16.03.2010
comment
Большое спасибо за это объяснение! Работает отлично! - person Elegya; 01.09.2010
comment
Спасибо за этот пост. Я читал об этом весь день, и в сети не было ничего, что направило бы меня в меню моделирования данных. Это сработало, и моя вера в Core Data возродилась :) - person Steve Neal; 09.10.2010
comment
См. Ответ Santthosh ниже, если после выполнения этих инструкций вы не можете объединить модели с двумя разными объектами с именем error. - person benvolioT; 17.11.2010
comment
Это решение на самом деле является частью реализации persistentStoreCoordinator: в XCode 4, но благодаря ему я могу понять, в чем проблема. - person JeroenEijkhof; 30.05.2011
comment
Хороший. Я рад, что Apple сделала это просто. Хотелось бы, чтобы некоторые из вещей, которые они делали, было легче различить. - person The Lazy Coder; 05.11.2011
comment
@Grouchal Tnx за помощь. Я последовал вашим предложениям и успешно перенес БД. Но все равно остался с запросом. Каждый раз, когда я вношу изменения в основные данные, если создается новая версия, я могу получить много файлов .xcdatamodel в моя исходная папка. Будет ли это иметь какие-либо другие неблагоприятные последствия в будущем ... Мой проект сильно зависит от основных данных ... Пожалуйста, ответьте как можно раньше, это действительно мне очень помогает .. - person Dinakar; 15.10.2012
comment
У меня уже было приложение в магазине, и всего несколько дней назад я загрузил его новую версию, не добавляя новую версию файла coredata на вкладке редактора после внесения изменений в файл БД, и, таким образом, приложение вылетало. Теперь я включил новая версия файла БД, таким образом, может видеть два файла .xcdatamodel в основном файле xcdatamodeld. Теперь, если я отправлю приложение с изменениями с новой версией… сможет ли пользователь получить доступ к приложению без сбоев. в большой нужде .. - person Dinakar; 15.10.2012
comment
@efrank - Единственный способ ответить на все 100% - это протестировать! Я не могу комментировать, какие изменения вы могли внести! - person Grouchal; 18.10.2012
comment
Новое расположение опций меню: Главное меню - ›Редактор -› Добавить версию модели. Чтобы установить текущую версию, вы теперь найдете ее на правой боковой панели, на вкладке File Inspector, в разделе Model Version с раскрывающимся списком Current. - person eselk; 23.03.2015

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

person Scott Means    schedule 02.08.2009
comment
Чистая сборка тоже устранила мои проблемы. - person jrainbow; 13.09.2009

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

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

person Santthosh    schedule 01.07.2010

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

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

person dreyln    schedule 15.02.2011

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

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

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

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

Отметьте это сообщение в блоге.

person samvermette    schedule 30.01.2011


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

Как только я убедился, что в моих новых столбцах установлен флажок «optional», я снова попробовал миграцию, и это сработало.

person Brain2000    schedule 02.01.2012

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

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

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

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

person The Cappy    schedule 01.06.2013

iOS 4.0+

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"model" withExtension:@"momd"];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
person Stian Høiland    schedule 28.03.2013

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

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

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

person PGSeattle    schedule 17.10.2013