使用Swift 4 Decodable解析含混合属性值的JSON
嘿,这个场景我太熟悉了——JSON里的字段类型不固定确实是Swift Decodable的一个小坎儿,不过咱们用枚举就能完美解决!
核心思路:用枚举封装多类型值
因为你的fields对象里的子值可能是字符串、整数或者自定义对象,我们可以先定义一个遵循Decodable的枚举,把所有可能的类型都包含进去,然后在解码的时候自动匹配对应的类型。
步骤1:定义嵌套对象(如果有需要的话)
如果fields里的子对象有固定结构,先把它的结构体写出来:
struct NestedFieldObject: Decodable { let subKey: String let subValue: Int // 这里根据你实际的JSON结构添加属性 }
步骤2:定义处理多类型的枚举
这个枚举会负责解码字符串、整数和自定义对象:
enum FieldValue: Decodable { case string(String) case int(Int) case nestedObject(NestedFieldObject) init(from decoder: Decoder) throws { let container = try decoder.singleValueContainer() // 按顺序尝试解码不同类型,成功就赋值对应case if let strValue = try? container.decode(String.self) { self = .string(strValue) return } if let intValue = try? container.decode(Int.self) { self = .int(intValue) return } if let objValue = try? container.decode(NestedFieldObject.self) { self = .nestedObject(objValue) return } // 如果所有类型都匹配失败,抛出解码错误 throw DecodingError.dataCorruptedError( in: container, debugDescription: "无法识别的字段值类型" ) } }
步骤3:定义主响应结构体
把id、key和fields(类型为[String: FieldValue])都包含进来:
struct APIResponse: Decodable { let id: String let key: String let fields: [String: FieldValue] }
步骤4:解码并使用数据
现在就可以正常解码JSON数据了,之后通过switch枚举值来处理不同类型的字段:
// 假设你已经拿到了JSON数据jsonData do { let response = try JSONDecoder().decode(APIResponse.self, from: jsonData) // 遍历fields处理每个字段 for (fieldName, fieldValue) in response.fields { switch fieldValue { case .string(let str): print("\(fieldName): 字符串 -> \(str)") case .int(let num): print("\(fieldName): 整数 -> \(num)") case .nestedObject(let obj): print("\(fieldName): 嵌套对象 -> 子键:\(obj.subKey),子值:\(obj.subValue)") } } } catch { print("解码出错:\(error.localizedDescription)") }
扩展说明
- 如果
fields里还有其他类型(比如布尔值、数组),只需要给枚举添加对应的case,然后在init(from:)里多加一个解码分支就行。 - 如果某些字段可能为
null,可以添加.null的case,并在解码时尝试container.decodeNil()来处理。
内容的提问来源于stack exchange,提问作者UKDataGeek
相关产品推荐
相关产品推荐

