用示例代码的问题:
我们在版本的Schemav1中有两个Swift数据模型,并希望在下一个App版本中的一个模型中添加一个可选字段。
我已经测试了此代码,并且在iOS 18中效果很好。想在进行生产之前获得一次确认。
贝洛是示例代码。注意:我们的项目有25 +型号,并且难以将所有型号复制到Next版本的Schema
typealias Car = AppSchemaV1.Car
typealias User = AppSchemaV1.User
enum AppSchemaV1: VersionedSchema {
static var versionIdentifier = Schema.Version(1,0,0)
static var models: [any PersistentModel.Type] {
[Car.self, User.self]
}
}
extension AppSchemaV1 {
class Car {
let carName: String
let carPrice: String
init(name: String, price: String) {
carName = name
carPrice = price
}
}
class User {
let name: String
let id: String
init(name: String, id: String) {
self.name = name
self.id = id
}
}
在下一个应用程序Verison,我们将在汽车模型中添加可选属性。我们将保留Appschemav1。
我们将在下面更改typealias
typealias Car = AppSchemaV2.Car
typealias User = AppSchemaV1.User
我们将创建一个新版本的Schema来保持汽车模型
enum AppSchemaV2: VersionedSchema {
static var versionIdentifier = Schema.Version(2,0,0)
static var models: [any PersistentModel.Type] {
[Car.self, User.self]
}
}
extension AppSchemaV1 {
class Car {
let carName: String
let carPrice: String
var carType: String? // This is the change in next app version
init(name: String, price: String, carType: String? = nil) {
carName = name
carPrice = price
carType = carType
}
}
}
我们将创建下面的迁移计划。我们想进行自定义迁移,因为我们想在添加新列后调用功能。注意:该功能不是关于填充列数据
enum MigrationPlan: SchemaMigrationPlan {
static var schemas: [any VersionedSchema.Type] {
[AppSchemaV1.self, AppSchemaV2.self]
}
static let migrateV1toV2 = MigrationStage.custom(fromVersion: AppSchemaV1.self, toVersion: AppSchemaV2.self, willMigrate: nil { _ in
// call my function to do some operation
}
static var stage: [MigrationStage] {
[migrateV1toV2]
}
}
明确定义appschemav2.car
extension AppSchemaV2 {
class Car {
let carName: String
let carPrice: String
var carType: String? // New optional property
init(name: String, price: String, carType: String? = nil) {
self.carName = name
self.carPrice = price
self.carType = carType
}
}
}
用途 @compersist forproperties如果您使用的是SwiftData或类似的FrameWokr,请确保您的模型属性标记为 @persistist以使其持久
extension AppSchemaV2 {
class Car: PersistentModel {
@Persisted var carName: String
@Persisted var carPrice: String
@Persisted var carType: String? // New optional property
init(name: String, price: String, carType: String? = nil) {
self.carName = name
self.carPrice = price
self.carType = carType
}
}
}
在您的自定义迁移阶段进行ADD错误处理以处理迁移期间的任何潜在问题
static let migrateV1toV2 = MigrationStage.custom(
fromVersion: AppSchemaV1.self,
toVersion: AppSchemaV2.self,
willMigrate: { context in
// Perform pre-migration logic if needed
},
didMigrate: { context in
do {
// Call your function after migration
yourFunction()
} catch {
print("Migration failed: \(error)")
}
}
)
pocument自定义迁移的目的和所谓的功能将帮助其他开发人员了解迁移逻辑及其意图