You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift Codable解析遇keyNotFound错误,请求技术协助

解决Swift Codable解析JSON时的keyNotFound错误

嘿,这个问题我之前也碰到过!咱们一步步来拆解解决:

核心问题分析

你遇到的keyNotFound错误主要有两个原因:

  1. JSON键名与Swift属性名不兼容:JSON里的country-id、country-iso带连字符,但Swift属性名不能包含连字符,默认情况下Codable会直接用属性名去匹配JSON键,自然找不到。
  2. 解码层级错误:你的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 06:52:30