Автоматическая облегченная миграция Core Data — переключение с неверсионной на версионную модель данных

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

-(NSManagedObjectModel *)managedObjectModel {

    //NSLog(@"%s", __FUNCTION__);
    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
    //managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];

    NSString *mainPath = [[NSBundle mainBundle] pathForResource:@"myDatabase" ofType:@"momd"];

    NSURL *mainMomURL = [NSURL fileURLWithPath:mainPath];
    managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:mainMomURL];
    return managedObjectModel;
}

возвращает ошибку: * Завершение работы приложения из-за необработанного исключения "NSInvalidArgumentException", причина: "* -[NSURL initFileURLWithPath:]: нулевой строковый параметр"

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

managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];

Я получаю сообщение об ошибке: Завершение работы приложения из-за необработанного исключения «NSInvalidArgumentException», причина: «Невозможно объединить модели с двумя разными объектами с именами...

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


person SAHM    schedule 09.10.2011    source источник
comment
Надеюсь, Маркус Зарра взвесится..   -  person SAHM    schedule 09.10.2011
comment
Есть предположения? Я упускаю что-то очевидное?   -  person SAHM    schedule 10.10.2011


Ответы (1)


Ладно, прогресс. Согласно ответу Юдзи по этой ссылке: Не удается найти файл momd: проблемы с основными данными

, я решил пойти со строкой:

managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];

После установки старой версии на устройство, добавления некоторых данных, выполнения чистой сборки с новой версией и последующей установки новой версии на устройство все обновилось правильно. Собираюсь попробовать еще раз в симуляторе и с другими моими целями. Это сумасшествие, вам иногда кажется, что вы делаете то же самое, что и раньше, но иногда получаете другие результаты? Я опубликую обновление, как только продвинусь дальше....

РЕДАКТИРОВАТЬ: Некоторые интересные события. В нынешнем виде этот проект начинался как одно из моих приложений, и я добавил другое приложение с аналогичным кодом (в качестве отдельной цели) для повторного использования кода после того, как оба приложения были развернуты в магазине приложений. Поскольку их базы данных были практически одинаковыми, я просто использовал одну и ту же модель xcdata для обоих. Это работало нормально, пока... я не начал решать эту проблему с миграцией. Оказывается, приведенный выше код для manageObjectModel работает для исходной цели в проекте, но не для новой цели.

Затем я нашел этот комментарий Маркуса Зарры:

Вероятно, он либо переименовал модель, либо установил версию, и в обоих случаях старый скомпилированный файл .mom останется в каталоге сборки. Это причина № 1 этой ошибки, которую я видел.

по этой ссылке: Основные данные: ошибка , «Не удается объединить модели с двумя разными сущностями с именем «foo»»

Что ж, может быть, мы сейчас где-то здесь. Вопрос в том, нужно ли мне теперь привносить в проект мою другую, оригинальную модель данных, а также обновлять ИТ??? Куда мы отправимся отсюда?

РЕДАКТИРОВАТЬ: Хорошо, я думаю, что добился хорошего прогресса в этом вопросе. Пожалуйста, не стесняйтесь исправлять меня по любому из следующих вопросов. Но из того, что я узнал до сих пор:

Имя пакета должно остаться прежним, иначе возникнут проблемы с миграцией. Это означает, в моем понимании, вероятно, оставить название продукта как есть. Но похоже, что изменение отображаемого имени пакета (которое отличается от имени пакета и также задается в файле app-info.plist) не повредит делу и на самом деле выполняет цели или изменение имени пакета в первое место.

Кроме того (мой первоначальный вопрос!), ПОЛНОСТЬЮ нормально переключаться с неверсионной модели данных на версионную модель данных, и на самом деле ожидается, что это то, что обычно происходит с первой миграцией. Так что нет проблем.

Еще один извлеченный урок: имя модели данных и имя файла .sqlite не обязательно совпадают! Одна из моих (многих) ошибок заключалась в использовании имени файла .sqlite при поиске файла momd. КОГДА вы ищете файл momd (при настройке manageObjectModel в делегате приложения) — используйте имя файла xcdatamodel! В связи с этим я не был уверен, следует ли во время миграции использовать «mergedModelFromBundles» или «initWithContentsOfURL». Как только у меня были правильные имена файлов, initWithContentsOfURL работал нормально (мне еще нужно провести некоторое тестирование, но я заставил его работать с обоими целевыми приложениями, в симуляторе и на устройстве. Оценка.

Несколько слов о xcdatamodels и xCode 4 — какая головная боль. По какой-то причине я не могу удалить промежуточные/неиспользуемые/ненужные модели данных версии в xCode 4. Поэтому мне пришлось проделать много причудливой работы, чтобы получить их ТОЛЬКО правильно, включая удаление самих моделей (только ссылки ), внося изменения с помощью «Показать содержимое пакета» в Finder и добавляя модели обратно. При этом нужно быть ОЧЕНЬ осторожным. Одна очень интересная вещь, которую я обнаружил, заключается в том, что мне ДЕЙСТВИТЕЛЬНО нужны две xcdatamodels, по одной для каждой цели приложения, с которой я работаю, и что названия xcdatamodel должны совпадать с названиями ранее развернутой версии, чтобы миграция работала. Мало того, текущая модель должна быть без номера — она должна точно соответствовать имени модели в моем развернутом приложении.

Это было действительно сложно, потому что xCode 4 не всегда хотел сотрудничать, когда я переименовывал модели и устанавливал для разных моделей текущую версию. Одна интересная вещь заключалась в том, что когда мне нужно было установить модель, которая находилась под другой моделью в дереве, в качестве текущей модели, xcode не понравилось это во время выполнения. Поэтому мне буквально пришлось зайти в файл .xcodeproj в Finder (с закрытым приложением), показать содержимое пакета, отредактировать файл project.pbxproj и изменить порядок моделей данных, чтобы поместить текущую вверху списка.

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

person SAHM    schedule 10.10.2011