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

Swift调用API解码报错:期望Dictionary<String, Any>却得到数组

Swift JSON解码错误解决:Expected to decode Dictionary<String, Any> but found an array instead.

错误原因

你遇到的问题是JSON结构不匹配:API返回的根数据是一个水果对象数组([Fruit]),但你的代码里用FruitsData结构体(对应一个包含fruits字段的JSON对象/字典)去解码,解码器预期接收字典,实际拿到数组,因此触发错误。

修复方案

直接解码成[Fruit]类型即可,无需额外的FruitsData包装结构体,具体修改如下:

  1. 删除FruitsData结构体
  2. 修改getData方法中的解码逻辑,将目标类型改为[Fruit].self
  3. 调整后续的变量类型和打印代码

修改后的完整代码:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let url = "https://www.fruityvice.com/api/fruit/all"
        getData(from: url)
    }
    
    private func getData(from url: String) {
        guard let url = URL(string: url) else {
            print("Invalid URL")
            return
        }
        
        let task = URLSession.shared.dataTask(with: url, completionHandler: { data, response, error in
            
            guard let data = data, error == nil else {
                print("Something went wrong: \(error?.localizedDescription ?? "Unknown error")")
                return
            }
            
            var fruits: [Fruit]?
            do {
                fruits = try JSONDecoder().decode([Fruit].self, from: data)
            }
            catch {
                print(String(describing: error))
            }
            
            guard let json = fruits else {
                return
            }
            
            // 打印所有水果信息(可读性更强)
            json.forEach { fruit in
                print("水果名称:\(fruit.name),热量:\(fruit.nutritions.calories)大卡")
            }
            // 也可以直接打印整个数组
            // print(json)
            
        })
        
        task.resume()
    }

}

struct Fruit: Codable {
    let genus: String
    let name: String
    let id: Int
    let family: String
    let order: String
    let nutritions: NutritionList
}

struct NutritionList: Codable {
    let carbohydrates: Double
    let protein: Double
    let fat: Double
    let calories: Int
    let sugar: Double
}

补充说明

  • 新增了URL合法性校验,避免强制解包URL(string: url)!可能导致的崩溃
  • 优化了错误信息打印,方便排查问题
  • 示例中添加了遍历打印水果信息的代码,比直接打印数组可读性更好

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 18:10:48