Swift中JSON转[String:自定义Class]字典失败的问题排查
问题原因
JSONSerialization 仅负责将 JSON 数据转换为 Swift 基础数据类型(如 [String: Any]、数组、字符串等),它无法自动识别并映射到你的自定义类 Y 的实例上。你用 JSONEncoder 编码了 [String: Y] 类型的字典,但反序列化时选错了工具——JSONEncoder 的配对工具是 JSONDecoder,后者专门处理遵循 Codable 协议的自定义类型。
解决方案
直接使用 JSONDecoder 的 decode(_:from:) 方法,指定目标类型为 [String: Y].self,即可直接得到类型匹配的字典。
修改后的代码
class Y: Codable, Hashable { var a: String = "c" static func ==(lhs: Y, rhs: Y) -> Bool { return lhs.a == rhs.a } func hash(into hasher: inout Hasher) { hasher.combine(a) } } struct ContentView: View { var body: some View { VStack { Button ("Fix") { var y = Y() var yDict = [String: Y]() yDict["0"] = y do { let encodedData = try JSONEncoder().encode(yDict) let jsonString = String(data: encodedData, encoding: .utf8) // 替换JSONSerialization为JSONDecoder直接解码目标类型 let yyDictDec = try JSONDecoder().decode([String: Y].self, from: encodedData) print("yDict after decode") print(yyDictDec) } catch { print(error.localizedDescription) } print("x") } } } }
特殊场景处理(如需先用JSONSerialization)
如果因为业务需求必须先用 JSONSerialization 解析 JSON 结构,之后可以手动遍历 [String: Any],将每个值单独解码为 Y 实例:
let decoded = try JSONSerialization.jsonObject(with: encodedData, options: []) as? [String: Any] if let rawDict = decoded { var convertedDict = [String: Y]() for (key, value) in rawDict { if let valueData = try? JSONSerialization.data(withJSONObject: value) { if let yInstance = try? JSONDecoder().decode(Y.self, from: valueData) { convertedDict[key] = yInstance } } } print(convertedDict) }
这种方式较为繁琐,无特殊需求时优先使用 JSONDecoder 直接解码整个字典。
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

