Автоматическая облегченная миграция 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:]: параметр строки nil"

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

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

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

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

1 ответ

Решение

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

Я решил пойти с линии:

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

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

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

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

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

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

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

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

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

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

Другой извлеченный урок - имя модели данных и имя файла.sqlite не обязательно совпадают! Одной из моих (многих) ошибок было использование имени файла.sqlite при поиске файла momd. Когда вы ищете файл momd (при настройке managedObjectModel в делегате приложения) - используйте имя файла xcdatamodel! Кроме того, я не был уверен, что во время миграции мне следует использовать "mergedModelFromBundles" или "initWithContentsOfURL". Когда у меня были правильные имена файлов, initWithContentsOfURL работал нормально (у меня все еще есть тестирование, но я получил его для работы с обоими целями приложений, в симуляторе и на устройстве. Score.

Несколько слов о xcdatamodels и xCode 4 - какая головная боль. По какой-то причине я не могу удалить промежуточные / неиспользуемые / ненужные версии моделей данных в xCode 4. Поэтому мне пришлось приложить немало усилий, чтобы получить эти ПРОСТО права, включая удаление самих моделей (только ссылки), внесение изменений с помощью " "Показать содержимое пакета" в Finder и добавление моделей обратно. При этом следует быть ОЧЕНЬ осторожным. Одна очень интересная вещь, которую я обнаружил, заключается в том, что мне DID нужны две xcdatamodel, по одной для каждой цели приложения, с которой я работаю, и что названия xcdatamodel должны совпадать с названиями ранее развернутой версии, чтобы миграция работала. Не только это, но и текущая модель должна быть без номера - она ​​должна идеально соответствовать названию модели в моем развернутом приложении.

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

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

Другие вопросы по тегам