Упрощенная миграция CoreData дает сбой даже после добавления модели сопоставления

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

Когда я впервые запустил его, я получил несколько ошибок Cannot merge multiple root entity source tables into one destination entity root table.

Полная ошибка выглядит следующим образом:

Fatal error: Unresolved error Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo = {sourceURL=file:///Users/koen/Library/Developer/CoreSimulator/Devices/8E2C0F01-ABF3-4414-A01A-EE4FFEF8D187/data/Containers/Data/Application/B7A9A4EE-EB57-434F-B1A9-576DCD80CFBD/Library/Application%20Support/MyApp.sqlite, reason=Cannot migrate store in-place: Cannot merge multiple root entity source tables into one destination entity root table, destinationURL=file:///Users/koen/Library/Developer/CoreSimulator/Devices/8E2C0F01-ABF3-4414-A01A-EE4FFEF8D187/data/Containers/Data/Application/B7A9A4EE-EB57-434F-B1A9-576DCD80CFBD/Library/Application%20Support/MyApp.sqlite, NSUnderlyingError=0x6000019fb810 {Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo = {message=Cannot merge multiple root entity source tables into one destination entity root table, destinationRootEntity=IDManagedObject, NSUnderlyingException=Cannot merge multiple root entity source tables into one destination entity root table, sourceRootEntities=(
    Book,
    Author
), reason=Cannot merge multiple root entity source tables into one destination entity root table}}}, ["NSUnderlyingError": Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo = {message=Cannot merge multiple root entity source tables into one destination entity root table, destinationRootEntity=IDManagedObject, NSUnderlyingException=Cannot merge multiple root entity source tables into one destination entity root table, sourceRootEntities=(
    Book,
    Author
), reason=Cannot merge multiple root entity source tables into one destination entity root table}, "destinationURL": file:///Users/koen/Library/Developer/CoreSimulator/Devices/8E2C0F01-ABF3-4414-A01A-EE4FFEF8D187/data/Containers/Data/Application/B7A9A4EE-EB57-434F-B1A9-576DCD80CFBD/Library/Application%20Support/MyApp.sqlite, "sourceURL": file:///Users/koen/Library/Developer/CoreSimulator/Devices/8E2C0F01-ABF3-4414-A01A-EE4FFEF8D187/data/Containers/Data/Application/B7A9A4EE-EB57-434F-B1A9-576DCD80CFBD/Library/Application%20Support/MyApp.sqlite, "reason": Cannot migrate store in-place: Cannot merge multiple root entity source tables into one destination entity root table]: file MyApp/SceneDelegate.swift, line 96

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

После небольшого поиска Я обнаружил, что мне нужно добавить модель сопоставления для перехода между старой и новой версией. Поэтому я добавил это через Cmd-N в Xcode и выбрал исходную и конечную модели.

Но я все еще получаю сообщение об ошибке.

И shouldMigrateStoreAutomatically, и shouldInferMappingModelAutomatically установлены на true.

Что мне здесь не хватает?

Старая модель находится в текущем приложении, написанном на Objective-C, новая модель находится в новой версии приложения, написанного на Swift, и теперь также использует CloudKit. Использование Xcode 12.2.

Я рад добавить дополнительную информацию, если это необходимо, просто не знаю, что будет иметь отношение к вопросу.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
768
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

...если два существующих объекта не имеют общего родителя в источнике, они не могут иметь общего родителя в месте назначения.

Это то, что вы пытаетесь сделать, но это не может произойти автоматически.

Более длинный ответ на вопрос «почему» содержит некоторые детали того, как работают Core Data. Xcode не очень хорошо делает это очевидным.

  • Когда у вас есть два или более объекта без общего родительского объекта, Core Data рассматривает их как полностью независимые. В вашем SQLite есть таблица Book, таблица Author и так далее.
  • Когда у вас есть две или более сущности с общим родителем, Core Data рассматривает их как особые случаи одной и той же таблицы. В вашем SQLite есть таблица IDManagedObject. Core Data использует другую логику, чтобы решить, является ли запись в этой таблице Book, Author или чем-то еще.

Из-за этого то, что вы на самом деле делаете, — это объединение нескольких объектов в один новый объект. Core Data не знает, как сделать это автоматически, о чем сообщает сообщение об ошибке.

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

Чтобы внести это изменение, вам потребуется создать диспетчер миграции и написать код для выполнения миграции. Apple описывает это в разделе Настройка процесса миграции. Или, в зависимости от того, что именно вам нужно, могут быть другие решения, не требующие добавления нового родительского объекта.

Спасибо что подметил это. Должно быть, пропустил вашу первую цитату при исследовании этого. Единственная причина, по которой я это делаю, заключается в том, чтобы упростить доступ/извлечение общего атрибута. Поэтому вместо того, чтобы получать Author, Book и т. д., я могу просто получить доступ к IDManagedObject.

koen 14.12.2020 22:42

Если это для доступа к значениям после выборки, возможно, объявите протокол с общим атрибутом и согласуйте с ним ваши классы Core Data. Затем используйте протокол для обработки их как одного типа.

Tom Harrington 15.12.2020 02:03

Кстати, эта ссылка от 2012 года, и, что удивительно, я не могу найти ничего более свежего и использующего Swift о моделях отображения. Более того, на следующей странице написано: «Если вы используете iCloud, вы можете перенести содержимое магазина только с помощью автоматической упрощенной миграции». Правильно ли я понимаю, что, поскольку я использую CloudKit, пользовательская миграция вообще не будет работать?

koen 15.12.2020 03:55

Если он не обновлялся с 2012 года, значит, он не обновлялся с тех пор, как не существовало Cloud! Я не знаю, какая там ситуация. С точки зрения языка, хотя он и использует Objective-C, структура, классы и функции одинаковы.

Tom Harrington 15.12.2020 05:04

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