如何通过本地JSON维护Realm数据库且不覆盖已有数据、删除重复项
问题核心
- 你将随机生成的UUID字段
_id设为主键,但JSON解码逻辑中注释了_id的解码规则,每次解析JSON时都会为题目生成全新的_id,Realm无法通过主键识别重复题目,每次重载都会全量插入数据。 - 原有判断重复的逻辑完全失效:你写的
if realm.object(ofType: Question.self, forPrimaryKey: "_id" ) != nil是把字符串"_id"作为主键值查询,不可能匹配到任何题目,等于没有去重逻辑。 - 你尝试的解决方案中用
questionid查询重复,但主键仍然是_id,查询逻辑和主键不匹配,无法生效。
修复方案
步骤1:调整主键规则
既然questionid是每道题的固有唯一标识,直接把它设为主键,不需要额外用随机UUID做冗余主键,修改Question模型的主键配置:
override static func primaryKey() -> String? { return "questionid" }
不需要的话可以直接删除_id属性,避免后续逻辑混淆。
步骤2:重写JSON解析去重逻辑
修正原有错误的去重判断,同时把写入事务移到循环外提升性能,还可以保留用户已有的答题数据(score、color字段):
func parseJSON(jsonData: Data){ do { let decoder = JSONDecoder() let result = try decoder.decode([Question].self, from: jsonData) // 全局开启一次写入事务,不要在循环内重复开启 try realm.write { for question in result { // 用主键questionid查询是否已存在该题目 if let existQuestion = realm.object(ofType: Question.self, forPrimaryKey: question.questionid) { // 已存在的题目仅更新题目内容,保留用户答题状态 existQuestion.date = question.date existQuestion.text = question.text existQuestion.answer1 = question.answer1 existQuestion.answer2 = question.answer2 existQuestion.answer3 = question.answer3 existQuestion.answer4 = question.answer4 } else { // 不存在的新题目直接插入 realm.add(question) } } } } catch { print("解析JSON出错:\(error)") } }
修改完成后每次重载App只会新增JSON中新增的题目,已有题目不会重复插入,还能保留用户已有的答题记录。
内容的提问来源于stack exchange,提问作者mblay
相关产品推荐
相关产品推荐

