You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过本地JSON维护Realm数据库且不覆盖已有数据、删除重复项

问题核心

  1. 你将随机生成的UUID字段_id设为主键,但JSON解码逻辑中注释了_id的解码规则,每次解析JSON时都会为题目生成全新的_id,Realm无法通过主键识别重复题目,每次重载都会全量插入数据。
  2. 原有判断重复的逻辑完全失效:你写的if realm.object(ofType: Question.self, forPrimaryKey: "_id" ) != nil是把字符串"_id"作为主键值查询,不可能匹配到任何题目,等于没有去重逻辑。
  3. 你尝试的解决方案中用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 23:45:03