Swift 4中解码英国气象局JSON至对象报错:找不到locations键
解决英国气象局JSON转Swift对象时的keyNotFound错误
这个keyNotFound错误本质是你的Swift结构体和英国气象局返回的JSON结构不匹配,导致解码器找不到对应的"locations"键。我帮你一步步排查和解决:
1. 先搞清楚返回的JSON真实结构
这是最关键的一步!很多时候我们会想当然地假设JSON结构,实际却不是。你可以先把请求到的原始数据转成字符串打印出来,看看真实的JSON格式:
// 拿到网络请求返回的data后 if let jsonStr = String(data: responseData, encoding: .utf8) { print("实际返回的JSON:\n\(jsonStr)") }
比如英国气象局的API可能返回嵌套结构,顶层是"response"或者"data"字段,里面才包含"locations":
{ "apiVersion": "1.0", "data": { "locations": [ { "id": "123", "name": "London", ... } ] } }
如果你的结构体直接把locations作为顶层属性,那肯定会找不到这个键。
2. 编写和JSON结构完全匹配的Codable结构体
根据你打印出来的JSON结构,调整你的Swift结构体。比如上面的JSON示例,对应的结构体应该是嵌套的:
// 顶层响应结构体 struct WeatherAPIResponse: Codable { let apiVersion: String let data: WeatherData } // 包含locations的中间层结构体 struct WeatherData: Codable { let locations: [Location] } // 地点结构体 struct Location: Codable { let id: String let name: String // 其他你需要的属性,要和JSON里的键完全对应 }
另外要注意大小写和命名规则:如果JSON用的是蛇形命名(比如location_id),而Swift用驼峰(locationId),可以给解码器设置自动转换策略:
let decoder = JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase
3. 正确执行解码操作
确保你用顶层的结构体去解码,而不是直接用Location或者中间层:
do { let apiResponse = try decoder.decode(WeatherAPIResponse.self, from: responseData) // 这里就能拿到apiResponse.data.locations了,之后就可以存入Core Data saveLocationsToCoreData(apiResponse.data.locations) } catch { print("解码错误: \(error)") }
4. 额外排查点
- 确认你的API请求参数正确:如果请求参数错了,可能返回的是错误信息JSON(比如包含
"error"字段),而不是你预期的带locations的响应。 - 检查Core Data的实体和
Location结构体的属性映射:解码成功后,要把结构体的属性正确赋值给Core Data实体的属性,避免后续存储出错。
如果按照上面的步骤还是有问题,你可以把打印出来的JSON片段和你的结构体代码贴出来,这样能更精准地定位问题。
内容的提问来源于stack exchange,提问作者William Duckworth
相关产品推荐
相关产品推荐

