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

Swift Decodable解码报错:Expected to decode Array<Any> but found a dictionary instead 问题求助

解决Swift Decodable解码报错:Expected to decode Array but found a dictionary instead

别着急,这个问题其实是你的结构体层级和API返回的JSON结构不匹配导致的,咱们一步步来修正:

首先看你调用的API返回的JSON结构:

{ 
  "data": { 
    "contentResults": [
      { "id": 2, "title": "news report 1", "imageUrl": "www.image.com" }, 
      { "id": 1, "title": "news report 2", "imageUrl": "www.image.com" }
    ] 
  } 
}

这里的层级是:根对象 → data对象 → contentResults数组,但你的TopLevel结构体直接声明了contentResults,相当于告诉解码器“在根层级找一个叫contentResults的数组”,但根层级只有data这个字典,所以就会报你看到的错误。

修正后的结构体定义

我们需要严格匹配JSON的层级结构,同时遵循Swift的命名规范(类型名首字母大写,单数类型对应数组元素):

// 根层级结构体,对应最外层的JSON对象
struct TopLevelResponse: Codable {
    let data: ContentData
}

// 对应JSON里的data对象
struct ContentData: Codable {
    let contentResults: [ContentResult]
}

// 对应数组里的单个元素
struct ContentResult: Codable {
    let id: Int
    let title: String
    let imageUrl: String
    // 因为属性名和JSON字段完全一致,所以可以省略CodingKeys,编译器会自动生成
}

解码示例

现在用JSONDecoder解码就可以正常工作了:

let jsonData = yourApiResponseData // 替换成你实际获取的Data
do {
    let response = try JSONDecoder().decode(TopLevelResponse.self, from: jsonData)
    let newsItems = response.data.contentResults
    print(newsItems) // 这里就能拿到正确解码后的数组了
} catch {
    print("解码失败:\(error)")
}

额外的优化点

  • 结构体命名尽量表意清晰,比如把TopLevel改成TopLevelResponse,contentResults改成ContentResult(单数,因为每个实例是单个结果),这样代码可读性更强。
  • 如果JSON字段和Swift属性名完全一致,不需要手动写CodingKeys,编译器会自动处理,减少冗余代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 11:07:34