Swift中Codable对象数组存JSON文件报错求助
解决Swift中Codable数组保存为JSON文件的错误问题
这个问题我之前也碰到过,核心是搞混了JSONSerialization和Codable的用法边界,咱们一步步来解决:
错误原因
你直接把[Products]?/[Inspirations]?类型的数组传给JSONSerialization.jsonObject(with:),但这个方法要求的参数是Data类型,而不是自定义的Codable结构体数组——JSONSerialization只负责处理Foundation原生类型(比如NSArray、NSDictionary)和JSON数据的互转,不认咱们自己定义的Codable对象,所以才会报类型不匹配的错误。
正确解决方案:用JSONEncoder处理Codable对象
既然你的结构体已经遵循了Codable协议,直接用JSONEncoder把数组转换成Data,再写入文件就好,这才是Codable设计的正确打开方式。我们可以写一个通用的复用函数,然后在你的saveTempToFinnalFiles里调用:
1. 定义通用保存函数
这个函数可以处理任何遵循Codable的数组类型,还能处理可选值和路径问题:
func saveCodableArray<T: Codable>(_ array: [T]?, to fileName: String) throws { // 先解包可选数组,为空的话抛出错误(你也可以根据需求改成空数组处理) guard let targetArray = array else { throw NSError(domain: "FileSaveError", code: 0, userInfo: [NSLocalizedDescriptionKey: "待保存的数组为空"]) } // 初始化JSON编码器,可选开启格式化让JSON更易读 let encoder = JSONEncoder() encoder.outputFormatting = .prettyPrinted // 把Codable数组编码成Data let jsonData = try encoder.encode(targetArray) // 获取Documents目录的URL(你可以根据需求换成其他目录,比如临时目录) guard let documentsDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { throw NSError(domain: "FileSaveError", code: 1, userInfo: [NSLocalizedDescriptionKey: "无法获取Documents目录"]) } // 拼接最终文件的URL let fileURL = documentsDir.appendingPathComponent(fileName) // 把Data写入文件 try jsonData.write(to: fileURL) }
2. 在你的函数中调用
修改saveTempToFinnalFiles函数,调用上面的通用方法保存两个数组:
func saveTempToFinnalFiles() { do { try saveCodableArray(products, to: "products.json") try saveCodableArray(inspirations, to: "inspirations.json") print("两个JSON文件保存成功!") } catch { print("保存失败:\(error.localizedDescription)") } }
额外说明
如果你非要用JSONSerialization(其实完全没必要,多此一举),那得先把Codable数组转成Data,再用JSONSerialization.jsonObject(with:)转成Foundation类型,最后再转回Data写入文件——这绕了一圈,不如直接用JSONEncoder高效简洁,所以不推荐这种方式。
内容的提问来源于stack exchange,提问作者triff
相关产品推荐
相关产品推荐

