Swift Codable解析JSON报KeyNotFound(id)错误如何解决
问题产生原因
- 配置的请求地址错误:代码中
NetworkService里写的请求地址和标注的待解析接口地址不一致,请求到了结构不匹配的其他接口,返回的data数组下首个元素不含id字段,直接触发键不存在的报错。 - 字段映射存在笔误:
Car结构体手动编写的CodingKeys中,foundationDate映射的键名为foundationDate,和常规接口返回的蛇形键名foundation_date不匹配,即使请求地址正确,解析到该字段时也会抛出错误。 - 未做字段兼容:模型中所有字段都声明为非可选类型,只要接口返回对应字段缺失、值为null,就会直接终止整个解析流程抛出错误。
修复方案
按以下步骤调整即可:
- 替换
NetworkService中的请求地址为正确的待解析接口地址,确保拿到的返回结构和预期一致。 - 移除手动编写的
CodingKeys,给JSONDecoder设置keyDecodingStrategy为.convertFromSnakeCase,自动完成蛇形命名到驼峰命名的字段映射,避免手写映射的笔误。 - 如果接口无法保证所有字段100%返回有效值,将可能缺失的字段声明为可选类型,单字段异常不会导致整个响应解析失败。
修正后的模型代码:
struct CarResponse: Codable { let result: Int let data: [Car] } struct Car: Codable { // 若确认接口一定返回id,可去掉?改为非可选String let id: String? let brandName: String let founderNames: [String] // 若日期字段可能缺失,同样可声明为String? let foundationDate: String }
修正后的网络请求与解析代码:
protocol NetworkServiceProtocol { func fetchData(completion: @escaping (Result<CarResponse?, Error>) -> Void) } class NetworkService: NetworkServiceProtocol { func fetchData(completion: @escaping (Result<CarResponse?, Error>) -> Void) { // 替换为正确的接口地址 let urlString = "对应正确的待解析接口地址" guard let url = URL(string: urlString) else { return } URLSession.shared.dataTask(with: url) { data, _, error in if let error = error { completion(.failure(error)) print(error.localizedDescription) return } guard let data = data else { return } do { let decoder = JSONDecoder() // 开启自动蛇形转驼峰映射 decoder.keyDecodingStrategy = .convertFromSnakeCase let obj = try decoder.decode(CarResponse.self, from: data) print(obj) completion(.success(obj)) } catch { print(String(describing: error)) completion(.failure(error)) } }.resume() } }
调试提示:如果修改后仍有解析错误,可以在debug时打印返回的JSON原始字符串,逐字段对比模型定义和返回结构的差异,快速定位不匹配的字段。
内容的提问来源于stack exchange,提问作者kesape
相关产品推荐
相关产品推荐

