Swift如何解码嵌套JSON?Codable协议不兼容报错如何解决?
错误原因
你的报错核心是 Codable 自动合成逻辑的匹配规则问题:CodingKeys 枚举的case名称必须和结构体的存储属性名完全一致,只有case的rawValue才是和JSON键名对应的映射值。你在Values结构体中定义的属性叫queryinfo,但CodingKeys里写的是case queryURL = "queryInfo",case名和属性名完全不匹配,系统找不到对应的属性来完成编解码,就会抛出不遵守Decodable/Encodable协议的错误。
同时你还要匹配目标API返回的实际JSON层级:根节点下承载嵌套数据的键是value而非你代码里写的values,需要对应调整映射。
修正后可运行代码
import UIKit // 类型名遵循Swift规范使用大驼峰 struct QueryInfo: Codable { let queryURL: String } struct Value: Codable { let queryInfo: QueryInfo // 如果要自定义属性名可以用CodingKeys映射,示例: // let customQueryInfoName: QueryInfo // private enum CodingKeys: String, CodingKey { // case customQueryInfoName = "queryInfo" // } } struct Post: Codable { let name: String let value: Value // 和JSON根节点的键对应 } let url = URL(string: "https://waterservices.usgs.gov/nwis/iv/?format=json&indent=on&sites=08155200¶meterCd=00065&siteStatus=all")! URLSession.shared.dataTask(with: url) { data, _, error in if let error = error { print("请求错误:\(error)") return } guard let data = data else { return } do { let result = try JSONDecoder().decode(Post.self, from: data) print("解码成功,queryURL为:\(result.value.queryInfo.queryURL)") } catch { print("解码错误:\(error)") } }.resume()
额外优化建议
- 尽量不要使用
try!强制解包解码结果,一旦JSON结构变动会直接导致程序崩溃,建议用do-catch捕获错误方便排查。 - 如果需要获取更深层级的数据(比如水位监测值),只需要按照JSON的层级继续扩展对应的Codable结构体即可。
内容的提问来源于stack exchange,提问作者Colin Miller
相关产品推荐
相关产品推荐

