You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SwiftData修改@Model数据结构后应用无法启动的问题咨询

SwiftData修改@Model数据结构后应用无法启动的问题咨询

嗨,这个问题我之前开发SwiftData项目的时候也碰到过!你遇到的NSCocoaErrorDomain 134110错误,本质是SwiftData(底层基于CoreData)的模型不兼容导致的迁移问题

当你一开始用旧的Item模型创建了持久化存储文件后,后续修改模型(比如新增newAtt属性),新的模型元数据和已经存在的旧存储文件的元数据就不匹配了,SwiftData默认情况下无法自动处理这种不匹配,所以就会抛出错误导致App启动失败。

下面给你两种场景的解决办法:

开发测试阶段(还没上线,不需要保留旧数据)

这种情况最直接:

  • 直接卸载模拟器/真机上的旧App,然后重新运行项目。旧的持久化存储文件会被彻底删除,新模型会生成符合要求的新存储文件。
  • 或者先在Xcode里执行Product -> Clean Build Folder(快捷键Cmd+Shift+K),再卸载旧App重新运行,确保没有缓存的旧模型数据。

正式上线/需要保留用户数据的场景

如果你的App已经有用户在使用,或者需要保留现有数据,那就必须配置模型自动迁移
SwiftData支持轻量级自动迁移,你只需要在初始化ModelContainer的时候,开启对应的配置选项就行。示例代码如下:

let container: ModelContainer
do {
    // 配置模型和存储选项
    let config = ModelConfiguration(schema: Schema([Item.self]))
    var options = ModelConfiguration.Options()
    // 开启自动 schema 迁移
    options.automaticallyMigratesSchema = true
    config.options = options
    
    container = try ModelContainer(for: Item.self, configurations: config)
} catch {
    fatalError("初始化ModelContainer失败:\(error)")
}

⚠️ 注意:轻量级迁移只支持简单的模型变更,比如新增可选属性、新增实体、将非可选属性改为可选属性等。如果是复杂变更(比如删除属性、修改属性数据类型、重命名属性/实体),SwiftData目前的自动迁移支持有限,可能需要更复杂的手动处理方案。

另外补充一点:你修改后的Item模型初始化方法要求必须传入newAtt,如果是从旧模型迁移过来的旧数据,建议给这个新增的非可选属性设置默认值,比如:

@Model
final class Item {
    var timestamp: Date
    var newAtt: String = "默认值" // 给新增的非可选属性加默认值

    init(timestamp: Date, newAtt: String = "默认值") {
        self.timestamp = timestamp
        self.newAtt = newAtt
    }
}

这样迁移的时候,旧数据的newAtt会自动填充默认值,避免因为属性缺失导致的迁移失败。

备注:内容来源于stack exchange,提问作者MisakaTang

火山引擎 最新活动