如何修复Swift解码JSON时的‘decoding could not find key CodingKeys’错误?
问题分析与修正方案
你的Codable结构体和JSON结构完全不匹配,这是解码失败的核心原因,具体问题如下:
核心不匹配点
根层级结构错误
- JSON根节点的
results是对象数组,但你定义成了String?; - JSON里的
previous、next、page、size是根层级的字段,你却放到了ResultsEA结构体里; - 根结构体里的
dimensions、metrics、EAResults都是JSON里不存在的字段。
- JSON根节点的
ResultsEA结构错误
- JSON的
results数组元素里没有eaRevenue这类键,而是用**有序数组metrics**来存储这四个数值; - 你定义的
eaRevenue等属性找不到对应JSON键,直接导致解码报错。
- JSON的
修正后的结构体实现
根据JSON结构,我们需要自定义解码逻辑来把metrics数组的元素映射到对应的属性,完整代码如下:
// 根结构体,对应JSON最外层结构 struct APIRootEA: Codable { let results: [ResultEA] let previous: String? let next: String? let page, size: Int } // 对应results数组中的单个对象 struct ResultEA: Codable { let dimensions: [Any]? // 因为JSON里是空数组,可根据实际类型调整,比如[String]? let eaRevenue: Double? // 注意第二个metrics值是小数,用Double而非Int let eaTransactions: Int let eaVisits: Int let eaActiveUrls: Int // 自定义解码逻辑,解析metrics数组 init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) dimensions = try container.decodeIfPresent([Any].self, forKey: .dimensions) // 解析metrics数组 let metrics = try container.decode([Double].self, forKey: .metrics) eaRevenue = metrics.count > 0 ? metrics[0] : nil eaTransactions = metrics.count > 1 ? Int(metrics[1]) : 0 // 小数转Int,根据需求调整 eaVisits = metrics.count > 2 ? Int(metrics[2]) : 0 eaActiveUrls = metrics.count > 3 ? Int(metrics[3]) : 0 } enum CodingKeys: String, CodingKey { case dimensions, metrics } }
关键说明
- 注意原始返回的JSON中
metrics第二个值是小数(如289198.5079709999),所以对应eaRevenue要用Double类型,避免解码失败; - 自定义
init(from:)方法时,加入了数组越界判断,避免因metrics元素数量不足导致崩溃; dimensions字段在JSON中是空数组,可根据实际返回的维度类型调整(比如如果是字符串数组,改成[String]?)。
内容的提问来源于stack exchange,提问作者flaneur_7508
相关产品推荐
相关产品推荐

