Импорт старой модели CoreData в новый проект

У меня есть старый проект Xcode, который содержит модель CoreData (содержащую версию 1 и версию 2 модели). По нескольким причинам мне нужно создать новый проект Xcode и перенести весь код в новый проект.

Как я могу импортировать/перенести мою старую модель CoreData таким образом, чтобы этот новый двоичный файл по-прежнему мог читать и, возможно, переносить существующие хранилища CoreData, которые находятся на iPhone и iPad моих существующих пользователей в мире? Я беспокоюсь, что если я отправлю новую версию, используя этот новый проект, мои пользователи обновят свое приложение до самой новой версии, а затем произойдет сбой, потому что номера модели или версии модели не совпадают.

Я НЕ говорю о добавлении новой версии в модель данных в том же приложении. Я понимаю этот процесс. Речь идет о перемещении/импорте/и т. д. существующей модели данных из старого проекта в новый проект.

Должен ли я просто скопировать файлы и добавить их в свой проект вручную? Нужно ли мне что-то менять в настройках сборки, чтобы учесть это?


person Kenny Wyland    schedule 17.03.2012    source источник


Ответы (3)


В итоге вот как я это решил:

  1. Создайте новый проект с CoreData
  2. Скопируйте необработанный файл модели CoreData в мой новый проект. Добавьте его в проект.
  3. Удалите пустую модель CoreData, автоматически созданную новым проектом.
  4. В настройках проекта в разделе «Фазы сборки» «Компилировать источники» я добавил скопированный файл модели CoreData.

Затем я использовал код, который Скотт предоставил выше:

[NSManagedObjectModel mergedModelFromBundles:nil]

который автоматически находит все модели и объединяет их. Удалив автоматически сгенерированный и добавив мой переданный, все работает нормально.

person Kenny Wyland    schedule 27.03.2012
comment
Привет, так что, просто загрузив объектную модель с помощью [NSManagedObjectModel mergedModelFromBundles: nil], я смогу получить существующие данные? Я пытаюсь запросить таблицу, но она возвращает 0, а база данных sqlite кажется пустой. Скотт указывает на этот другой код — › [[NSManagedObjectModel alloc] initWithContentsOfURL:[NSURL fileURLWithPath:modelPath]]. - person Edoardo Moreni; 28.09.2016
comment
Xcode 8: мне просто нужно было вытащить модель из другого проекта. Шаги 1-4 отлично сработали для меня! - person leanne; 29.09.2016
comment
@leanne, поэтому для инициализации основных данных и объектной модели вы оставили код, который Xcode предоставляет при создании нового проекта? - person Edoardo Moreni; 01.10.2016
comment
Да, @EdoardoMoreni: да. Однако мой файл модели замены имел то же имя, что и файл модели, созданный Xcode. Если имя файла вашей модели отличается, вам придется обновить код и настройки, чтобы отображалось правильное имя файла модели. - person leanne; 05.10.2016

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

Позвольте мне отредактировать это немного дальше. Понижение имеет грустный.

Существует таблица ZMETADATA (или эквивалентная, сейчас не могу до нее добраться), в которой есть вся информация, необходимая для идентификации вещей. Кроме того, есть хэши, чтобы узнать, присутствуют ли текущие версии, чтобы могла произойти автоматическая миграция. Если хэши существуют и вы загрузили свою модель через [[NSManagedObjectModel alloc] initWithContentsOfURL:[NSURL fileURLWithPath:modelPath]] вместо [NSManagedObjectModel mergedModelFromBundles:nil], тогда все должно быть хорошо.

person Scott Corscadden    schedule 17.03.2012
comment
Я не спрашиваю о том, как перезаписать двоичный файл моего приложения. Когда этот новый двоичный файл запускается и начинает читать существующее хранилище приложений, автоматическая миграция требует, чтобы хранилище данных и модель данных совпадали. Если они не совпадают, код CoreData выдаст исключение, и приложение выйдет из строя. - person Kenny Wyland; 17.03.2012
comment
Да… и при условии, что у вас есть те же версии Core Data .xcdatamodeld в приложении на основе одного и того же идентификатора приложения, миграция произойдет за вас. Просто добавить их в ваш текущий проект должно быть достаточно, да. - person Scott Corscadden; 18.03.2012
comment
Мне не ясно, какой код должен работать. Я пытаюсь загрузить объектную модель с помощью [NSManagedObjectModel mergedModelFromBundles:nil], что было предложено @KennyWyland, но это не работает. Я также пытался использовать [[NSManagedObjectModel alloc] initWithContentsOfURL:[NSURL fileURLWithPath:modelPath]], но все ломается. - person Edoardo Moreni; 28.09.2016

Я нашел более простой способ. Я создал новый проект с основными данными, а затем закрыл его, не создавая и не запуская его. Затем я использовал IDE, чтобы открыть файл xcdatamodeld. Текстовый редактор, вероятно, будет работать так же хорошо. Пришлось углубляться в содержание. Это может быть потому, что я использую PHPStorm, и он пытается сделать из этого проект. Файл, который я хотел отредактировать, выглядел так:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0"   lastSavedToolsVersion="1" systemVersion="11A491" minimumToolsVersion="Automatic"   sourceLanguage="Swift" userDefinedModelVersionIdentifier="">
</model>

Затем я открыл исходный xcdatamoleld и скопировал все, что находится между тегами модели, в новый файл. Я закрыл файлы и построил проект. Я не копировал фактические данные модели (.storedata).

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

CoreData: warning: Unable to load class named 'Performance' for entity 'Performance'.  Class not found, using default NSManagedObject instead.

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

Это было с Xcode 8.2.1, и это был проект Swift.

person curt    schedule 14.01.2017
comment
Редактирование внутренней части файлов — верный способ внедрить демонов и испортить ваш проект. Это хорошая идея, чтобы позволить Xcode управлять этими вещами для вас, тем более что они могут меняться от версии к версии. - person Kenny Wyland; 15.01.2017
comment
ОП спрашивал об импорте существующей модели в новый проект. Там нечего "накручивать". Даже если это не сработало, нужно просто удалить новый проект и создать другой. У меня есть второй проект, который находится далеко в своем развитии. Я бы не стал использовать этот метод на нем. Если бы Apple предоставила методы для импорта существующей модели, нам не понадобился бы этот пост. - person curt; 15.01.2017