Swift中如何自定义解码含动态类型的API响应?
Swift自定义解码不同类型对象的实现方案
要解决这种由key字段标识object类型的JSON解码问题,核心是在解码包含key和object的结构体时,先获取key的值,再根据它解析对应类型的object。以下是完整的实现代码和关键说明:
修正并完善后的解码代码
struct Response: Decodable { let data: [DataItem] } struct DataItem: Decodable { let key: String let object: ObjectType // 自定义解码逻辑 init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) // 先解码key字段,确定object的类型 self.key = try container.decode(String.self, forKey: .key) // 根据key值分支处理object的解码 switch self.key { case "word": let wordValue = try container.decode(String.self, forKey: .object) self.object = .word(wordValue) case "number": let numberValue = try container.decode(Int.self, forKey: .object) self.object = .number(numberValue) default: // 遇到未知key时抛出明确错误,便于调试 throw DecodingError.dataCorruptedError( forKey: .key, in: container, debugDescription: "无法识别的key类型:\(self.key)" ) } } // 定义JSON字段对应的编码键 private enum CodingKeys: String, CodingKey { case key, object } } enum ObjectType: Decodable { case word(String) case number(Int) // 修正原枚举名,与JSON的key值保持一致 }
关键说明
- 解码时机选择:必须在
DataItem(原代码中的Objects)结构体中实现自定义解码,因为ObjectType的类型依赖于同层级的key字段,单独解码ObjectType时无法获取key的值。 - 分支解码逻辑:先解码
key,再根据key的取值,将object字段解码为对应类型(字符串/整数),最后创建ObjectType枚举实例。 - 错误处理:针对未知的
key类型抛出解码错误,避免静默失败,方便排查问题。 - 命名一致性:修正枚举成员名为
number,与JSON中的key: "number"对应,保持代码语义清晰。
解码使用示例
// 标准格式的JSON字符串(注意原示例JSON的key需要加双引号) let jsonString = """ { "data": [ { "key": "word", "object": "hello" }, { "key": "number", "object": 15 } ] } """ do { let data = jsonString.data(using: .utf8)! let response = try JSONDecoder().decode(Response.self, from: data) // 遍历解码结果 for item in response.data { switch item.object { case .word(let text): print("单词类型:\(text)") case .number(let num): print("数字类型:\(num)") } } } catch { print("解码失败:\(error)") }
内容的提问来源于stack exchange,提问作者Noah Iarrobino
相关产品推荐
相关产品推荐

