Swift 5下混合类型与键控/无键混合结构JSON解码问题求助
Swift 5 异构JSON解码解决方案
步骤1:定义内层混合类型枚举
用于处理同一数组中同时存在Int和String类型的元素
enum StringOrInt: Codable { case int(Int) case string(String) init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() // 优先尝试解码Int类型 if let intVal = try? container.decode(Int.self) { self = .int(intVal) return } // 解码Int失败则尝试解码String类型 if let stringVal = try? container.decode(String.self) { self = .string(stringVal) return } // 两种类型都不匹配抛出异常 throw DecodingError.dataCorruptedError(in: container, debugDescription: "Value is neither Int nor String") } }
步骤2:定义外层异构数组元素枚举
用于处理外层无键数组中同时存在Int、字典、String三种类型的元素
enum OuterElement: Codable { case int(Int) case dict([String: [StringOrInt]]) case string(String) init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() // 匹配整数类型 if let intVal = try? container.decode(Int.self) { self = .int(intVal) return } // 匹配键控字典类型,值为混合类型数组 if let dictVal = try? container.decode([String: [StringOrInt]].self) { self = .dict(dictVal) return } // 匹配字符串类型 if let stringVal = try? container.decode(String.self) { self = .string(stringVal) return } throw DecodingError.dataCorruptedError(in: container, debugDescription: "Unsupported outer element type") } }
步骤3:解码调用示例
// 加载JSON数据 let jsonData = """ [ 12, { "a": [ "orange", 10, "purple" ], "b": [ "red", 9, "blue" ], "c": [ "yellow", "green" ] }, "string one", "string two" ] """.data(using: .utf8)! // 执行解码 do { let decodeResult = try JSONDecoder().decode([OuterElement].self, from: jsonData) // 取值示例 for item in decodeResult { switch item { case .int(let num): print("外层整数:\(num)") case .dict(let dict): print("外层字典内容:") for (key, valueArr) in dict { print("键\(key)的数组元素:") valueArr.forEach { element in switch element { case .int(let num): print(" 整数:\(num)") case .string(let str): print(" 字符串:\(str)") } } } case .string(let str): print("外层字符串:\(str)") } } } catch { print("解码错误:\(error.localizedDescription)") }
核心逻辑说明
- 所有异构类型统一用带关联值的Codable枚举封装,不需要手动解析整个JSON结构,仅处理类型匹配分支即可
- 解码时按优先级尝试匹配类型,兼容异常场景,代码可维护性高
- 后续使用时通过switch匹配枚举case即可安全取值,不会出现类型转换崩溃问题
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

