Realm Swift菜谱应用List关联对象主键相关报错问题咨询
问题根因
你遇到的两个报错是本地模型与服务端Schema不匹配 + 本地Realm版本迁移冲突共同导致的,具体拆解如下:
- 第一个报错要求
recipe_ingredients加主键的原因:你把配料、步骤类声明成了独立的Object子类,启用同步的Realm要求所有独立Object类必须有_id作为主键 - 加主键后出现第二个报错的原因:
- 本地已经存在旧版本的Realm文件,旧的
recipe_ingredients表没有主键,新增主键属于模型结构变更,没有做迁移处理就会触发结构变更报错 - 你的服务端Schema没有把
recipe_ingredients、recipe_steps配置为独立集合,仅把它们作为recipe表的内嵌对象,两边结构不一致导致同步校验失败
- 本地已经存在旧版本的Realm文件,旧的
解决方案
推荐优先选择改动最小的内嵌对象适配方案,匹配你现有服务端Schema配置:
步骤1:修改Swift端模型
配料、步骤属于菜谱的内嵌附属数据,不需要作为独立集合存储,将它们的父类从Object改为EmbeddedObject即可,内嵌对象不需要配置主键:
// 菜谱类保持不变 class recipe: Object { @Persisted(primaryKey: true) var _id: ObjectId = ObjectId.generate() // 建议加默认值避免空主键 @Persisted var name: String? @Persisted var category: String? @Persisted var image: String? @Persisted var note: Double? @Persisted var likes: Int? @Persisted var ingredients: List<recipe_ingredients> @Persisted var steps: List<recipe_steps> @Persisted var time: String? @Persisted var units: Int? convenience init(name: String) { self.init() self.name = name } } // 改为EmbeddedObject,删除主键 class recipe_ingredients: EmbeddedObject{ @Persisted var name: String? @Persisted var quantity: String? } // 改为EmbeddedObject,删除主键,同时修正字段映射匹配服务端 class recipe_steps: EmbeddedObject{ @Persisted(originProperty: "description") var step_description: String? // 映射服务端的description字段 @Persisted var step: Int? }
步骤2:处理本地Realm冲突
开发阶段直接卸载App重装,清空本地旧的Realm文件即可消除迁移报错;如果是已上线版本,需要升高Realm的schemaVersion,在迁移配置中处理旧模型数据的转换逻辑。
可选方案:保留独立集合
如果你需要把配料、步骤作为独立的公共集合复用,可以选择调整服务端Schema:
- 服务端新增
recipe_ingredients、recipe_steps两个独立集合的Schema,分别配置_id为ObjectId类型的主键,补全对应字段 - 本地保持现有
Object子类的写法,给_id加默认生成值,同样卸载重装或者做迁移处理即可。
内容的提问来源于stack exchange,提问作者Charlotte DB
相关产品推荐
相关产品推荐

