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
相关产品推荐
相关产品推荐

