Контейнер не удается инициализировать после успешной миграции и инициализацииIOS

Программируем под IOS
Ответить
Anonymous
 Контейнер не удается инициализировать после успешной миграции и инициализации

Сообщение Anonymous »

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

Code=134504 «Невозможно использовать поэтапную миграцию с неизвестной версией модели».

Структура кода — сводка
Я использую versionedSchema для хранения нескольких моделей в SwiftData. Я начал сталкиваться с этой проблемой при добавлении двух новых моделей в новейшую версию схемы.
Начиная с текущей общедоступной версии V4.4.6, существует две миграции.
Сводка миграции:
Первая миграция — на V4.4.7. Это упрощенная миграция, удаляющая один
атрибут из одной из моделей. Это было протестировано и успешно сработало.
Второй переход — на версию 5.0.0. Это пользовательская миграция, в которую добавляются две новые модели и создаются экземпляры двух новых моделей на основе данных из экземпляров существующих моделей. При первоначальном тестировании этой версии проблем не наблюдалось.
Проблема и действия по ее воспроизведению
Воспроизведение проблемы: начиная со свежей сборки общедоступной версии V4.4.6, я запускаю новую сборку, содержащую обе версии схемы (V4.4.7 и V5.0.0), а также связанные с ними этапы миграции. Это успешно собирается, и контейнер успешно переносится на версию V5.0.0. При проверке файла default.store все значения переносятся и создаются правильно.
Вторым шагом в воспроизведении проблемы является просто прекращение запуска сборки, а затем перестройка без каких-либо изменений кода. После этого каждый раз не удается инициализировать контейнер модели. Возвращаясь к симулятору после остановки последовательных сборок в Xcode, приложение запускается и обращается к контейнеру модели или изменяет его как обычно.
Дополнительная проблема: я столкнулся с той же постоянной проблемой в холсте предварительного просмотра Xcode «Не удалось инициализировать контейнер модели». Это проблема сборки 5 из 6, при которой сборки будут работать в случайном порядке. В случае с предварительным просмотром я несколько раз удалил все данные, связанные со всеми предварительным просмотром. Единственная разница заключается в том, что симулятор дает 100% отказ после первоначальной успешной инициализации. Я предполагаю, что это связано с различной структурой сборки предварительных просмотров.
Наконец, следует отметить, что предварительные просмотры Xcode не могут создать экземпляр контейнера модели на той же строке, что и симулятор. Из моего исследования этой проблемы люди говорят, что предварительный просмотр Xcode создается из другого места. У меня есть отдельный контейнер модели, настроенный специально для предварительного просмотра холста, но ошибка возникает не в этом контейнере, а в основном контейнере приложения.
Возможные способствующие факторы и проверенные факты
iOS: хотя у меня были проблемы со SwiftData и компилятором в iOS 26, я могу исключить это как проблему здесь. Это было протестировано на симуляторах под управлением iOS 18.6, 26.0.1 и 26.1, и во всех случаях возникли сбои при инициализации контейнера модели. Хотя в iOS 18 последующие сборки после успешной миграции работали, в конечном итоге я столкнулся с той же ошибкой и сбоем. В iOS 26.0.1 и 26.1 эти ошибки возникают сразу во второй сборке.
Мой личный опыт: это моя первая миграция, включающая добавление новых моделей в мои схемы. У меня есть опыт облегченных и пользовательских миграций в versionedSchemas, но при первой сборке V5.0.0 у меня возникли трудности. Хотя этот код успешно создается и переносится, я считаю, что могу пропустить какой-то важный код, который сейчас вызывает проблемы.
Инициализация контейнера для версии 4.4.6

Код: Выделить всё

do {
container = try ModelContainer(
for:
Job.self,
JobTask.self,
Day.self,
Charge.self,
Material.self,
Person.self,
TaskCategory.self,
Service.self,

migrationPlan: JobifyMigrationPlan.self
)
} catch {
fatalError("Failed to Initialize Model Container")
}
Экземпляр схемы с версиями для версии 4.4.6 (версия 4.4.7 отличается только идентификатором версии)

Код: Выделить всё

static var versionIdentifier = Schema.Version(4, 4, 6)

static var models: [any PersistentModel.Type] {
[Job.self, JobTask.self, Day.self, Charge.self, Material.self, Person.self, TaskCategory.self, Service.self]
}
Инициализация контейнера для V5.0.0

Код: Выделить всё

    do {

let schema = Schema([Jobify.self,
JobTask.self,
Day.self,
Charge.self,
MaterialItem.self,
Person.self,
TaskCategory.self,
Service.self,
ServiceJob.self,
RecurerRule.self])

container = try ModelContainer(
for: schema, migrationPlan: JobifyMigrationPlan.self
)
} catch {
fatalError("Failed to Initialize Model Container")
}
Экземпляр схемы с версиями для версии 5.0.0

Код: Выделить всё

static var versionIdentifier = Schema.Version(5, 0, 0)

static var models: [any PersistentModel.Type] {
[
JobifySchemaV500.Job.self,
JobifySchemaV500.JobTask.self,
JobifySchemaV500.Day.self,
JobifySchemaV500.Charge.self,
JobifySchemaV500.Material.self,
JobifySchemaV500.Person.self,
JobifySchemaV500.TaskCategory.self,
JobifySchemaV500.Service.self,
JobifySchemaV500.ServiceJob.self,
JobifySchemaV500.RecurerRule.self
]
}
Этапы миграции | V4.4.6 -> V4.4.7, V4.4.7 -> V5.0.0

Код: Выделить всё

static var migrateV446toV447 = MigrationStage.lightweight(fromVersion: JobifySchemeV446.self, toVersion: JobifySchemeV447.self)

static var V447toV500 = MigrationStage.custom(
fromVersion: JobifySchemeV447.self,
toVersion: JobifySchemaV500.self,
willMigrate: nil,
didMigrate: { context in

var services: [JobifySchemaV500.Service] = []

let descriptor: FetchDescriptor = FetchDescriptor(predicate: #Predicate { service in
service.rawFrequency != 0
})

do {
services = try context.fetch(descriptor)
} catch {
print("Failed to fetch JobifySchemaV500.Service from context")
}

var serviceJobs: [JobifySchemaV500.ServiceJob] = []

for service in services {
for job in service.jobs {

/// If service contains charges for Job, create a new serviceJob following the rules of the existing Service

if !service.charges.isEmpty && service.frequency != nil {
var serviceJob: JobifySchemaV500.ServiceJob = ServiceJob(from: job, and: service)

serviceJobs.append(serviceJob)

}
}
}

for serviceJob in serviceJobs {
context.insert(serviceJob)
}

do {
try context.save()
} catch {
print("Failed to save context after inserting [JobifySchemaV500.ServiceJob] during migration V447toV500")
}
}
)
Устранение различий в именах объектов
  • Псевдонимы типов: все мои типы моделей имеют псевдонимы типов для упрощения компонентов представления. Все типы имеют псевдонимы «JobifySchemeV446.» в версии V.4.4.6 и «JobifySchemeV500.» в версии V5.0.0
  • Проблемы с iOS 26: мои псевдонимы типов, относящиеся к iOS 17, перекрывались с объектами более низкого уровня в Swift, включая «Job» и «Материал». Это стало проблемой при инициализации контейнера модели при работе в iOS 26. С тех пор псевдонимы типов были переименованы, однако сборка V4.4.6 со старыми именами прекрасно работает и собирается в iOS 26
Если существует какой-либо другой код, который может иметь значение для определения места возникновения этой ошибки, я был бы рад его добавить. Моя лучшая теория на данный момент заключается в том, что я по ошибке пропустил код, относящийся к миграции SwiftData.

Подробнее здесь: https://stackoverflow.com/questions/798 ... ialization
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»