iOS中JSON文件加载保存异常:无法追加数据仅保留最新条目
问题解决:JSON追加数据失败的原因与修复方案
核心问题
你的代码里加载和保存的文件路径不一致:
loadCustomCadences从Bundle.main读取文件,这是应用安装时的内置只读目录,无法写入修改;saveCadences把数据写到Documents目录,这是用户可读写的沙盒目录。
所以每次加载的都是Bundle里的初始空数组,自然无法实现追加效果。
修复方案
统一读写路径到Documents目录,同时可保留Bundle文件作为首次启动的默认数据(可选)。
修改后的完整代码:
// 统一获取文件路径:固定指向Documents目录的目标文件 private func getCustomCadencesFileURL() -> URL { let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! return documentsDirectory.appendingPathComponent("customCadences.json") } func loadCustomCadences() -> [Cadence] { let fileURL = getCustomCadencesFileURL() // 优先读取用户已保存的文件 if FileManager.default.fileExists(atPath: fileURL.path) { do { let data = try Data(contentsOf: fileURL) return try JSONDecoder().decode([Cadence].self, from: data) } catch { print("加载已保存文件失败: \(error)") } } // 如果没有已保存文件,尝试读取Bundle里的默认数据(可选) if let bundleURL = Bundle.main.url(forResource: "customCadences", withExtension: "json") { do { let data = try Data(contentsOf: bundleURL) return try JSONDecoder().decode([Cadence].self, from: data) } catch { print("加载Bundle默认文件失败: \(error)") } } // 所有情况都失败则返回空数组 return [] } func saveCadences(_ cadence: Cadence) { var loadedCadences = loadCustomCadences() print("已加载的数据: \(loadedCadences)") do { loadedCadences.append(cadence) print("追加后的数据: \(loadedCadences)") let data = try JSONEncoder().encode(loadedCadences) let fileURL = getCustomCadencesFileURL() try data.write(to: fileURL) let jsonString = String(data: data, encoding: .utf8) ?? "无法解析JSON字符串" print("保存的JSON内容: \(jsonString)") } catch { print("保存JSON失败: \(error)") } }
关键改动说明
- 新增
getCustomCadencesFileURL()函数,统一管理文件路径,彻底避免路径不一致问题; loadCustomCadences()优先读取用户已保存的数据,不存在时再回退到Bundle默认数据;saveCadences()调用修改后的加载函数,确保读取到的是用户之前保存的全量数据,再进行追加和覆盖写入(JSON数组无法直接追加字节,必须先读全量再写入)。
内容的提问来源于stack exchange,提问作者JulienM
相关产品推荐
相关产品推荐

