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




