SwiftData: не удалось создать ModelContainer при миграцииIOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 SwiftData: не удалось создать ModelContainer при миграции

Сообщение Anonymous »

Мое приложение аварийно завершает работу при запуске при попытке создать SwiftData ModelContainer после создания состояния миграции из V1 в V2.
Вот сообщение об ошибке, которое я получаю: Тема 1: Неустранимая ошибка: не удалось выполнить создать ModelContainer для обуви: операцию не удалось завершить. (Ошибка SwiftData.SwiftDataError 1.)
Что изменилось в моей единственной модели с версии V1 на версию V2?
Я добавил новое свойство под названием defaultRunTypes: [RunType] где RunType — это перечисление с 5 различными вариантами.
Модель V1 имеет только свойство isDefaultShoe: Bool, и я хочу расширить функциональность, чтобы иметь несколько значений по умолчанию для разных типов run.
Теперь немного кода.
Вот как я создаю контейнер:
typealias Shoe = ShoesSchemaV2.Shoe

final class ShoesStore {

static let container = {
let container: ModelContainer

do {
container = try ModelContainer(for: Shoe.self, migrationPlan: ShoesMigrationPlan.self)
} catch {
fatalError("Failed to create ModelContainer for Shoe: \(error.localizedDescription)")
}

return container
}()
}

Это план миграции.
enum ShoesMigrationPlan: SchemaMigrationPlan {

static var schemas: [any VersionedSchema.Type] {
[ShoesSchemaV1.self, ShoesSchemaV2.self]
}

static var stages: [MigrationStage] {
[migrateV1toV2]
}

static let migrateV1toV2 = MigrationStage.custom(
fromVersion: ShoesSchemaV1.self,
toVersion: ShoesSchemaV2.self,
willMigrate: { context in
print("Migration: willMigrae")

let v1Shoes = try? context.fetch(FetchDescriptor())

for v1Shoe in v1Shoes ?? [] {
print("Migration: V1 Shoe: \(v1Shoe.brand) \(v1Shoe.model) - isDefaultShoe = \(v1Shoe.isDefaultShoe)")

let v2Shoe = ShoesSchemaV2.Shoe(
id: v1Shoe.id,
image: v1Shoe.image,
brand: v1Shoe.brand,
model: v1Shoe.model,
nickname: v1Shoe.nickname,
lifespanDistance: v1Shoe.lifespanDistance,
aquisitionDate: v1Shoe.aquisitionDate,
totalDistance: v1Shoe.totalDistance,
totalDuration: v1Shoe.totalDuration,
lastActivityDate: v1Shoe.lastActivityDate,
isRetired: v1Shoe.isRetired,
retireDate: v1Shoe.retireDate,
isDefaultShoe: v1Shoe.isDefaultShoe,
defaultRunTypes: v1Shoe.isDefaultShoe ? [.daily] : [], // this is the newly added property
workouts: v1Shoe.workouts,
personalBests: v1Shoe.personalBests,
totalRuns: v1Shoe.totalRuns
)

print("Migration: V2 shoe created: \(v1Shoe.brand) \(v1Shoe.model) - defaultRunTypes: \(v2Shoe.defaultRunTypes.count)")

context.insert(v2Shoe)
context.delete(v1Shoe)
}

try? context.save()
},
didMigrate: { context in
print("Migration: didMigrate")
let v2Shoes = try? context.fetch(FetchDescriptor())

for v2Shoe in v2Shoes ?? [] {
print("Migration: V2 shoe: \(v2Shoe.brand) \(v2Shoe.model) - defaultRunTypes: \(v2Shoe.defaultRunTypes.count)")
}
}
)
}

При миграции у меня есть следующий вывод на консоль. willMigrate выполняется, но не DidMigrate
Migration: willMigrate
Migration: V1 Shoe: Adidas Adizero Boston 12 - isDefaultShoe = true
Migration: V2 shoe created: Adidas Adizero Boston 12 - defaultRunTypes: 1
Migration: V1 Shoe: Nike Pegasus Turbo - isDefaultShoe = false
Migration: V2 shoe created: Nike Pegasus Turbo - defaultRunTypes: 0
Migration: V1 Shoe: Nike Zoomfly 5 - isDefaultShoe = false
Migration: V2 shoe created: Nike Zoomfly 5 - defaultRunTypes: 0
Migration: V1 Shoe: Nike Vaporfly 3 - isDefaultShoe = false
Migration: V2 shoe created: Nike Vaporfly 3 - defaultRunTypes: 0
Migration: V1 Shoe: Hoka Speedgoat 6 - isDefaultShoe = false
Migration: V2 shoe created: Hoka Speedgoat 6 - defaultRunTypes: 0

ShoeHealth/ShoesStore.swift:21: Fatal error: Failed to create ModelContainer for Shoe: The operation couldn’t be completed. (SwiftData.SwiftDataError error 1.)

Я не знаю, что здесь происходит, поскольку это моя первая миграция. Является ли способ создания ModelContainer проблемой (он статический — я делаю это, потому что мне также нужен доступ к нему в WidgetKit)?
Вот как я получаю доступ это в AppIntentTimelineProvider:
struct MediumShoeStatsTimelineProvider: AppIntentTimelineProvider {

let modelContext = ModelContext(ShoesStore.container)
// rest of the code, where I am using the modelContext to fetch models
}


Позднее редактирование:
Я попробовал перейти с пользовательского MigrationState на облегченный, и это работает. За исключением того факта, что defaultRunTypes пуст для всех ботинок, как и ожидалось, поскольку это значение по умолчанию.
Поэтому способ создания пользовательского MigrationState, я думаю, неправильный.
static let migrateV1toV2 = MigrationStage.lightweight(fromVersion: ShoesSchemaV1.self, toVersion: ShoesSchemaV2.self)


Подробнее здесь: https://stackoverflow.com/questions/793 ... -migrating
Реклама
Ответить Пред. темаСлед. тема

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

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

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

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

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • SwiftData: не удалось создать ModelContainer при миграции
    Anonymous » » в форуме IOS
    0 Ответы
    16 Просмотры
    Последнее сообщение Anonymous
  • SwiftData: не удалось создать ModelContainer при миграции
    Anonymous » » в форуме IOS
    0 Ответы
    15 Просмотры
    Последнее сообщение Anonymous
  • SwiftData: не удалось создать ModelContainer при миграции
    Anonymous » » в форуме IOS
    0 Ответы
    19 Просмотры
    Последнее сообщение Anonymous
  • SwiftData/ModelContainer.swift:144: Неустранимая ошибка: не удалось найти активный в данный момент контейнер для Student
    Гость » » в форуме IOS
    0 Ответы
    40 Просмотры
    Последнее сообщение Гость
  • SwiftData/ModelContainer.swift:144: Неустранимая ошибка: не удалось найти активный в данный момент контейнер для Student
    Anonymous » » в форуме IOS
    0 Ответы
    53 Просмотры
    Последнее сообщение Anonymous

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