Версионирование основных данных вручную - PullRequest
7 голосов
/ 20 июня 2011

Я разработал приложение, iCollege , и теперь я хочу сделать приложение намного лучше.
Во время тестирования я хотел восстановить данные из резервной копии.При запуске iCollege происходит сбой приложения, поскольку оно не может быть проверено версией Core Data.Теперь у меня вопрос: можно ли вручную создать файл базовых данных, т. Е. Пройти через каждый управляемый объект существующего файла и подогнать объекты к активной версии модели.

Возможно ли что-то подобное?

РЕДАКТИРОВАТЬ: Большое спасибо за быстрый и подробный ответ.Я думаю, что я объяснил свой вопрос не очень хорошо.Вот еще одно описание моей проблемы.
У меня есть файл, созданный с помощью Core Data с несколькими объектами объектов Course и Teacher.Я заменяю файл Core Data моего приложения этим файлом.Когда приложение запустится в следующий раз, я хочу вызвать метод, который считывает управляемые объекты файла с объектами Course и Teacher и преобразует его в сущности, например, Subject и Professor.Атрибуты также могут быть изменены.У меня вопрос: могу ли я это сделать, то есть могу ли я самостоятельно создать версию файла Core Data?
Надеюсь, теперь мой вопрос можно проверить.: -)

Ответы [ 2 ]

32 голосов
/ 20 июня 2011

Хотя теоретически вы можете переносить данные вручную, это, вероятно, не стоит затраченных усилий.Вы хотите использовать automatic lightweight migration.

Чтобы выполнить автоматическую облегченную миграцию, вам нужно настроить две модели данных, а затем в коде вы скажете Core Data выполнить миграцию.Это означает, что вы не должны изменять свою модель данных до тех пор, пока вы не закончите чтение .Если у вас есть, (автоматически или вручную) восстановить старую модель.Он понадобится вам для миграции.Вот как работает автоматическая облегченная миграция:

Сначала необходимо добавить версию модели в модель данных.Выберите существующую модель, а затем добавьте версию из меню Editor:

Select the model

Add a Model Version

Вам будет предложено указать модель данных ивыберите существующую модель, на которой она будет основана.

enter image description here

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

enter image description here

Убедитесь, что ваша модель выбрана в левой рукенавигатор, иначе вы можете не увидеть опции справа.Вы должны получить что-то вроде этого:

enter image description here

(я на самом деле использую здесь версию 2 вместо версии 3, но идея та же.)

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

Внутри вашего persistentStoreCoordinator метода в делегате приложения измените эту строку:

if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]){

к следующему (добавление в строке, предшествующей оператору if):

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];


if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]){

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

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

5 голосов
/ 08 августа 2011

Вы можете сделать это следующим образом.Базовые данные позволяют добавлять несколько постоянных хранилищ в NSPersistentStoreCoordinator, поэтому вам нужно два хранилища, связанных с вашим координатором.Обратите внимание, что невозможно использовать две разные модели управляемых объектов (MOM), у вас может быть только одна MOM для всех ваших магазинов.

Хотя это может показаться довольно сложным, но вместо этого это достаточно просто, учитывая, что Core Data также позволяет использовать конфигурации.Конфигурация имеет имя и связанный набор сущностей.Наборы могут перекрываться, то есть данный объект может появляться в нескольких конфигурациях.См. Соответствующую документацию

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

Что-то вроде (просто пример фрагмента):

NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] init];
[coordinator addPersistentStoreWithType:type configuration:@"CourseAndTeacher" URL:aURL options:nil error:NULL];
[coordinator addPersistentStoreWithType:type configuration:@"SubjectAndProfessor" URL:anotherURL options:nil error:NULL];

NSManagedObjectContext *context = [[NSManageObjectContext alloc] init];
[context setPersistentStoreCoordinator:coordinator];
...