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

Swift使用JSONDecoder报“No value associated with key”错误排查

问题根源:JSON结构与Swift解码结构体不匹配

你遇到的"No value associated with key"错误,核心原因是你的JSON数据嵌套层级和Swift结构体的期望完全不一致,解码器找不到对应字段,自然无法完成解析。

具体来说:

  • 你的JSON中,sections数组里的每一项都被包裹在"section"这个key下(比如{"section": {"title": "Main Settings", ...}}),但你的Section结构体直接期望顶级的title和items字段;
  • 同样,每个items数组里的元素也被包裹在"item"key下(比如{"item": {"title": "Notifications", ...}}),但你的Item结构体直接期望顶级的title、type、url字段。

解决方法:二选一即可

方法1:修正JSON结构(推荐,更简洁)

直接去掉多余的嵌套包裹,让JSON结构和你的结构体完全对齐:

{
  "sections": [
    {
      "title": "Main Settings",
      "items": [
        {
          "title": "Notifications",
          "type": "notification",
          "url": ""
        },
        {
          "title": "Log Out",
          "type": "",
          "url": ""
        }
      ]
    },
    {
      "title": "Feedback",
      "items": [
        {
          "title": "Contact Us",
          "type": "email",
          "url": ""
        },
        {
          "title": "Rate on App Store",
          "type": "webView",
          "url": "https://www.apple.com/uk/ios/app-store/"
        }
      ]
    },
    {
      "title": "About",
      "items": [
        {
          "title": "Terms of Service",
          "type": "webView",
          "url": ""
        },
        {
          "title": "Privacy Policy",
          "type": "webView",
          "url": "https://www.apple.com/uk/ios/app-store/"
        },
        {
          "title": "Version Info",
          "type": "webView",
          "url": ""
        }
      ]
    }
  ]
}

修改后,你原来的Swift结构体(还可以删掉多余的CodingKeys,因为属性名和JSON key完全一致,Decodable会自动映射)就能正常解码了。

方法2:调整Swift结构体适配现有JSON

如果不能修改JSON,就需要给结构体添加中间层来匹配嵌套结构:

fileprivate struct SettingsPayload: Decodable {
    let sections: [SectionWrapper]
    
    // 用来包裹section的中间结构体
    struct SectionWrapper: Decodable {
        let section: Section
    }
}

struct Section: Decodable {
    let title: String
    let items: [ItemWrapper]
    
    // 用来包裹item的中间结构体
    struct ItemWrapper: Decodable {
        let item: Item
    }
}

struct Item: Decodable {
    let title: String
    let type: String
    let url: String
}

然后解码时需要把中间层的实际数据提取出来:

if let url = Bundle.main.url(forResource: fileName, withExtension: "json") { 
    do { 
        let data = try Data(contentsOf: url) 
        let payload = try JSONDecoder().decode(SettingsPayload.self, from: data)
        // 提取实际的sections和items数据
        let actualSections = payload.sections.map { wrapper in
            Section(
                title: wrapper.section.title,
                items: wrapper.section.items.map { $0.item }
            )
        }
        completion(actualSections) 
    } catch { 
        print("解码错误:\(error)")
        completion(nil) 
    } 
}

另外补充一点:你原结构体里的CodingKeys是多余的,因为属性名和JSON key完全一致,Swift的Decodable会自动完成映射,不需要手动声明。

内容的提问来源于stack exchange,提问作者Constantinos Theophilou

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:53:04