Swift Decodable:能否将JSON部分节点读取为字符串而非数据结构?
Swift Codable 解析JSON时将指定节点转为字符串
要实现把JSON中的def节点(JSON对象)直接读取为字符串,不能直接用decode(String.self)(因为该节点是JSON对象而非原生字符串类型),可以通过先将节点解码为任意JSON对象,再序列化为Data后转成字符串的方式实现,完整代码如下:
import Foundation let json = #""" { "abc": 123, "def": { "xyz": "hello world!" } } """# // 自定义类型,用于解码任意JSON对象(支持嵌套结构) private struct JSONObject: Decodable { let value: Any init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() // 依次兼容解析不同类型的JSON值 if let intValue = try? container.decode(Int.self) { value = intValue } else if let stringValue = try? container.decode(String.self) { value = stringValue } else if let boolValue = try? container.decode(Bool.self) { value = boolValue } else if let doubleValue = try? container.decode(Double.self) { value = doubleValue } else if let arrayValue = try? container.decode([JSONObject].self) { value = arrayValue.map { $0.value } } else if let dictValue = try? container.decode([String: JSONObject].self) { value = dictValue.mapValues { $0.value } } else { throw DecodingError.dataCorruptedError(in: container, debugDescription: "无法解析该JSON节点") } } } struct X: Decodable { let abc: Int let def: String enum CodingKeys: String, CodingKey { case abc case def } init(decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) // 正常解析abc字段 abc = try container.decode(Int.self, forKey: .abc) // 处理def字段:先解码为JSON对象,再转回JSON格式字符串 let defObject = try container.decode(JSONObject.self, forKey: .def) let defData = try JSONSerialization.data(withJSONObject: defObject.value, options: []) guard let defString = String(data: defData, encoding: .utf8) else { throw DecodingError.dataCorruptedError(forKey: .def, in: container, debugDescription: "无法将JSON节点转换为字符串") } def = defString } } // 测试解析逻辑 do { let x = try JSONDecoder().decode(X.self, from: json.data(using: .utf8)!) print(x.abc) // 输出:123 print(x.def) // 输出:{"xyz":"hello world!"} } catch { print(error) }
关键说明
- 自定义
JSONObject类型:兼容解析所有JSON基础类型及嵌套结构,将其转为Any类型保存,确保能处理任意复杂的JSON节点。 - 字符串转换逻辑:通过
JSONSerialization将解码后的JSON对象重新序列化为Data,再转为字符串,保证输出的是标准JSON格式字符串。 - 格式化输出可选:如果需要带缩进的格式化JSON字符串,可将
JSONSerialization.data的options参数改为.prettyPrinted。
内容的提问来源于stack exchange,提问作者drekka
相关产品推荐
相关产品推荐

