I am a develop beginner. Recently, my App used SwiftData's MigraitonPlan, which caused it to crash when I opened it for the first time after updating in TestFlight or the store. After clicking it a second time, I could enter the App normally, and I could confirm that all the models were the latest versions.However, when I tested it in Xcode, everything was normal without any errors.
Here is my MigrationPlan code:
import Foundation
import SwiftData
enum MeMigrationPlan: SchemaMigrationPlan {
static var schemas: [any VersionedSchema.Type] {
[MeSchemaV1.self, MeSchemaV2.self, MeSchemaV3.self, MeSchemaV4.self]
}
static var stages: [MigrationStage] {
[migrateV1toV2, migrateV2toV3, migrateV3toV4]
}
//migrateV1toV2, because the type of a data field in MeSchemaV1.TodayRingData.self was modified, the historical data was deleted during the migration, and the migration work was successfully completed.
static let migrateV1toV2 = MigrationStage.custom(
fromVersion: MeSchemaV1.self,
toVersion: MeSchemaV2.self,
willMigrate: { context in
try context.delete(model: MeSchemaV1.TodayRingData.self)
},
didMigrate: nil
)
//migrateV2toV3, because a new Model was added, it would crash at startup when TF and the official version were updated, so I tried to delete the historical data during migration, but the problem still exists.
static let migrateV2toV3 = MigrationStage.custom(
fromVersion: MeSchemaV2.self,
toVersion: MeSchemaV3.self,
willMigrate: { context in
try context.delete(model: MeSchemaV2.TodayRingData.self)
try context.delete(model: MeSchemaV2.HealthDataStatistics.self)
try context.delete(model: MeSchemaV2.SportsDataStatistics.self)
try context.delete(model: MeSchemaV2.UserSettingTypeFor.self)
try context.delete(model: MeSchemaV2.TodayRingData.self)
try context.delete(model: MeSchemaV2.TodayHealthData.self)
try context.delete(model: MeSchemaV2.SleepDataSource.self)
try context.delete(model: MeSchemaV2.WorkoutTargetData.self)
try context.delete(model: MeSchemaV2.WorkoutStatisticsForTarget.self)
try context.delete(model: MeSchemaV2.HealthDataList.self)
},
didMigrate: nil
)
//migrateV3toV4, adds some fields in MeSchemaV3.WorkoutList.self, and adds several new Models. When TF and the official version are updated, it will crash at startup. Continue to try to delete historical data during migration, but the problem still exists.
static let migrateV3toV4 = MigrationStage.custom(
fromVersion: MeSchemaV3.self,
toVersion: MeSchemaV4.self,
willMigrate: { context in
do {
try context.delete(model: MeSchemaV3.WorkoutList.self)
try context.delete(model: MeSchemaV3.HealthDataStatistics.self)
try context.delete(model: MeSchemaV3.SportsDataStatistics.self)
try context.delete(model: MeSchemaV3.UserSettingTypeFor.self)
try context.delete(model: MeSchemaV3.TodayRingData.self)
try context.delete(model: MeSchemaV3.TodayHealthData.self)
try context.delete(model: MeSchemaV3.SleepDataSource.self)
try context.delete(model: MeSchemaV3.WorkoutTargetData.self)
try context.delete(model: MeSchemaV3.WorkoutStatisticsForTarget.self)
try context.delete(model: MeSchemaV3.HealthDataList.self)
try context.delete(model: MeSchemaV3.SleepStagesData.self)
try context.save()
} catch {
print("Migration from V3 to V4 failed with error: \(error)")
throw error
}
},
didMigrate: nil
)
}