Swift解码含动态属性名的JSON数据问题
解决Swift解码动态Key的JSON问题
你的问题出在误用了singleValueContainer()——这个容器是用来解码单个值(比如纯数字、纯字符串这类非JSON对象的结构),但接口返回的是完整的JSON字典,所以会抛出类型不匹配的错误。
正确的做法是先获取整个字典容器,过滤掉已知的date键,剩下的唯一键就是动态的汇率键,再解码对应的值:
struct RateResponse: Decodable { let date: String let rate: Double let currencyCode: String // 可选字段,用来存储动态的货币代码(比如eur、usd) init(from decoder: Decoder) throws { // 获取整个JSON字典的容器 let container = try decoder.container(keyedBy: CodingKeys.self) // 解码固定的date字段 date = try container.decode(String.self, forKey: .date) // 过滤出所有非date的键 let remainingKeys = container.allKeys.filter { $0 != .date } // 确保至少有一个汇率键存在 guard let rateKey = remainingKeys.first else { throw DecodingError.dataCorrupted( DecodingError.Context( codingPath: container.codingPath, debugDescription: "响应中未找到汇率字段" ) ) } // 解码动态键对应的汇率值 rate = try container.decode(Double.self, forKey: rateKey) // 保存货币代码(如果不需要可以删掉这一行) currencyCode = rateKey.stringValue } // 仅定义固定的date键,动态键通过allKeys处理 enum CodingKeys: String, CodingKey { case date } }
代码说明
- 先通过
keyedBy获取整个JSON字典容器,解码固定的date字段。 - 用
allKeys拿到所有键,过滤掉date后剩下的就是动态的汇率键。 - 对这个动态键解码得到汇率值,还可以顺便保存货币代码(如果业务需要的话)。
- 增加了错误判断,避免没有汇率键的情况导致崩溃。
内容的提问来源于stack exchange,提问作者Lukasz D
相关产品推荐
相关产品推荐

