Swift Codable解析遇keyNotFound错误,请求技术协助
解决Swift Codable解析JSON时的keyNotFound错误
嘿,这个问题我之前也碰到过!咱们一步步来拆解解决:
核心问题分析
你遇到的keyNotFound错误主要有两个原因:
- JSON键名与Swift属性名不兼容:JSON里的
country-id、country-iso带连字符,但Swift属性名不能包含连字符,默认情况下Codable会直接用属性名去匹配JSON键,自然找不到。 - 解码层级错误:你的JSON根对象包含
metadata和data字段,CA对象是嵌套在data下的,直接解码CA.self相当于告诉解码器“整个JSON就是一个CA对象”,这和实际结构不匹配。
具体解决步骤
1. 修正结构体的CodingKeys映射
如果quicktype生成的结构体没有自动添加CodingKeys枚举,你需要手动补上,把带连字符的JSON键映射成合法的Swift属性名:
struct CA: Codable { let countryId: String? let countryIso: String? // 其他属性... // 关键:添加CodingKeys枚举映射JSON键 enum CodingKeys: String, CodingKey { case countryId = "country-id" case countryIso = "country-iso" // 其他属性对应的JSON键也需要在这里映射 } }
2. 定义顶层响应结构体匹配JSON层级
你需要先创建一个包含metadata和data的顶层结构体,再通过它解码出嵌套的CA对象:
// 先定义Metadata结构体(根据你的JSON实际字段调整) struct Metadata: Codable { let status: String? let timestamp: String? // 其他metadata字段... } // 顶层响应结构体 struct ApiResponse: Codable { let metadata: Metadata? let data: CA? }
3. 正确执行解码
现在用顶层结构体来解码,而不是直接解码CA.self:
let decoder = JSONDecoder() do { let response = try decoder.decode(ApiResponse.self, from: jsonData) // 从响应中取出CA对象 if let caData = response.data { print("Country ID: \(caData.countryId ?? "未知")") print("Country ISO: \(caData.countryIso ?? "未知")") } } catch { print("解码错误详情:\(error)") }
完整示例(结合你的JSON结构)
假设你的JSON是这样的:
{ "metadata": { "status": "success", "timestamp": "2024-05-20T10:00:00Z" }, "data": { "country-id": "123", "country-iso": "CA", "country-name": "Canada" } }
对应的完整Swift代码:
import Foundation struct Metadata: Codable { let status: String? let timestamp: String? } struct CA: Codable { let countryId: String? let countryIso: String? let countryName: String? enum CodingKeys: String, CodingKey { case countryId = "country-id" case countryIso = "country-iso" case countryName = "country-name" } } struct ApiResponse: Codable { let metadata: Metadata? let data: CA? } // 解码测试 let jsonString = """ { "metadata": { "status": "success", "timestamp": "2024-05-20T10:00:00Z" }, "data": { "country-id": "123", "country-iso": "CA", "country-name": "Canada" } } """ if let jsonData = jsonString.data(using: .utf8) { let decoder = JSONDecoder() do { let response = try decoder.decode(ApiResponse.self, from: jsonData) if let ca = response.data { print("解析成功:") print("ID: \(ca.countryId!)") print("ISO: \(ca.countryIso!)") print("Name: \(ca.countryName!)") } } catch { print("解码失败:\(error.localizedDescription)") } }
额外提示
如果quicktype生成的结构体总是漏掉CodingKeys,你可以在生成时勾选“Use CodingKeys”选项(不同版本的quicktype位置可能不同),这样它会自动帮你生成键映射。
内容的提问来源于stack exchange,提问作者The Bear
相关产品推荐
相关产品推荐

