Swift/SwiftUI中Realm如何使用同一模型将数据存入不同表
问题根因
你当前复用了同一个Question模型存储「选中题目」和「错题」两类业务数据,Realm查询Question.self时会返回所有该类型的存储对象,自然会同时返回两类题目数据,同个题目多次存储也会出现重复条目。
解决方案
方案1:新建独立错题表(推荐,业务隔离最清晰)
直接新增独立的错题模型,和原有Question字段完全一致,两类数据完全分开存储,不会互相干扰:
- 新增模型定义
struct WrongQuestion: Codable, Realmable, Hashable { var id: String = "" var question: String = "" var imageURL: String = "" var sections: [String : String] = [:] var correct: String = "" var isQuestionImage: Bool = false var isSectionImage: Bool = false var selected: String = "" // 可选:设置主键避免重复存储 static func primaryKey() -> String? { return "id" } }
- 修改存储、查询逻辑
// 存储错题 func saveWronQuestionToRealm(wrongQuestion: Question) { guard let realmReferance = try? Realm() else { return } // 转换为错题模型实例 let wrongModel = WrongQuestion(id: wrongQuestion.id, question: wrongQuestion.question, imageURL: wrongQuestion.imageURL, sections: wrongQuestion.sections, correct: wrongQuestion.correct, isQuestionImage: wrongQuestion.isQuestionImage, isSectionImage: wrongQuestion.isSectionImage, selected: wrongQuestion.selected) do { try realmReferance.write({ // 有主键的话用update参数避免重复写入 realmReferance.add(wrongModel, update: .modified) }) } catch let error { print(error) } } // 查询错题 func getWrongQuestionFromToRealm() -> [WrongQuestion]? { if let realmReferance = try? Realm() { let result = realmReferance.objects(WrongQuestion.self).reversed() return Array(result) } return nil }
方案2:原有模型加标记字段(无需新建表)
给Question模型新增业务标记字段,存储时区分类型,查询时过滤即可:
- 修改
Question模型
struct Question: Codable, Realmable, Hashable { var id: String = "" var question: String = "" var imageURL: String = "" var sections: [String : String] = [:] var correct: String = "" var isQuestionImage: Bool = false var isSectionImage: Bool = false var selected: String = "" // 新增标记字段:是否是错题 var isWrong: Bool = false }
- 修改存储、查询逻辑
// 存储错题 func saveWronQuestionToRealm(wrongQuestion: Question) { guard let realmReferance = try? Realm() else { return } // 先校验是否已存储过同id的错题,避免重复 if let exist = realmReferance.object(ofType: Question.self, forPrimaryKey: wrongQuestion.id), exist.isWrong { return } do { try realmReferance.write({ var newWrong = wrongQuestion newWrong.isWrong = true realmReferance.add(newWrong) }) } catch let error { print(error) } } // 查询错题 func getWrongQuestionFromToRealm() -> [Question]? { if let realmReferance = try? Realm() { // 加过滤条件,只查标记为错题的条目 let result = realmReferance.objects(Question.self).filter("isWrong == true").reversed() return Array(result) } return nil }
内容的提问来源于stack exchange,提问作者Ufuk Köşker
相关产品推荐
相关产品推荐

