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")
}
Код: Выделить всё
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]
}
Код: Выделить всё
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")
}
Код: Выделить всё
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
]
}
Код: Выделить всё
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
Подробнее здесь: https://stackoverflow.com/questions/798 ... ialization
Мобильная версия