错误:“应解码 Dictionary<String, Any>,但找到了一个数组。” ——但我还没有定义字典? [复制]

Posted

技术标签:

【中文标题】错误:“应解码 Dictionary<String, Any>,但找到了一个数组。” ——但我还没有定义字典? [复制]【英文标题】:Error: "Expected to decode Dictionary<String, Any> but found an array instead." — but I haven't defined a dictionary? [duplicate] 【发布时间】:2021-07-29 01:44:58 【问题描述】:

我正在从事一个创意项目,我正在尝试使用 Swift 的 JSONDecoder() 函数从 API 数据库中解码内容。我已经构建了我的结构,一个 getData() 函数,并且我已经为 JSONDecoder() 函数设置了一个 do-try-catch。我很难理解我正在做什么来得到我得到的错误。

这是我的结构:

struct Response: Codable 
    let foundRecipes: [Recipe]
    let foundIngredients: [Ingredient]


struct Recipe: Codable 
    let id: Int
    let title: String
    let image: String
    let imageType: String
    let usedIngredientCount: Int
    let missedIngredientCount: Int
    let missedIngredients: [Ingredient]
    let usedIngredients: [Ingredient]
    let unusedIngredients: [Ingredient]
    let likes: Int


struct Ingredient: Codable 
    let id: Int
    let amount: Int
    let unit: String
    let unitLong: String
    let unitShort: String
    let aisle: String
    let name: String
    let original: String
    let originalString: String
    let origianalName: String
    let metaInformation: [String]
    let meta: [String]
    let image: String

这是我的 getData() 函数:

    func getData(from url: String) 
    URLSession.shared.dataTask(with: URL(string: url)!, completionHandler:  data, response, error in
        guard let data = data, error == nil else 
            print("something went wrong.")
            return
        
        var result: Response?
        do 
            result = try JSONDecoder().decode(Response.self, from: data)
        
        catch 
            print("")
            print(String(describing: error)) // Right here is where the error hits.
        
        
        guard let json = result else 
            return
        
        print(json.foundRecipes)
    ).resume()

这里是 API 文档的链接。我在 getData() 中调用的 URL 链接到与他们的示例中所示相同的搜索结构:https://spoonacular.com/food-api/docs#Search-Recipes-by-Ingredients - 这是我正在处理的确切搜索的 url 结果的屏幕截图:https://imgur.com/a/K3Rn9SZ

最后,这是我发现的完整错误:

typeMismatch(Swift.Dictionary, Swift.DecodingError.Context(codingPath: [], debugDescription: "期望解码 Dictionary 但找到了一个数组。", 基础错误: nil ))

我对这个错误的理解是,它是说我告诉 JSONDecoder() 查找 的字典,但它在链接中并且只看到一个数组。我很困惑,因为我不知道它认为我在哪里提供字典。我在哪里搞砸了?不是在寻找特定的代码更改,只是对我所缺少的内容的一些指导。

提前致谢:)

【问题讨论】:

你能发布一个你从 url 获得的典型 json 响应数据吗? 为了清楚起见,json 中的字典可以是 swift 中的自定义类型,如类或结构 它可能是字典,这就是错误显示字典的原因即使它是我们最常使用的结构。 【参考方案1】:

正如您在 API 数据图像和链接到的 API 文档中所见,API 正在返回一个数组(例如,在文档中,您可以看到它被 [...] 包围)。实际上,看起来 API 返回了一个 Recipe 的数组。

因此,您可以将解码调用更改为:

var result: [Recipe]?
do 
   result = try JSONDecoder().decode([Recipe].self, from: data)
   print(result)
 catch 
  print(error)

也许您对Response 的想法来自其他地方,但是foundRecipesfoundIngredients 的键没有出现在这个特定的API 调用中。


另外,感谢 @workingdog 的有用评论,关于在您的模型中将 amount 更改为 Double 而不是 Int

【讨论】:

除了实现这个答案之外,让你在食谱和成分中的变量成为可选的。另请注意,在成分中,数量是 Double 而不是 Int。 @workingdog 将所有内容都设为可选是不好的做法。 API 显然在发送一致的数据。这样做的缺点是如果返回错误nil,您将不知道出了什么问题。 成功了!它消除了我在制作结构时所扮演的角色的所有困惑。非常感谢:)

以上是关于错误:“应解码 Dictionary<String, Any>,但找到了一个数组。” ——但我还没有定义字典? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Informix 错误:发生了语法错误。错误代码:-201

我收到一个错误:“MetaMask - RPC 错误:错误:错误:[ethjs-rpc] rpc 错误与有效负载”

错误精灵错误跟踪器错误

网页打开显示错误500是啥意思

PHP错误处理

PHP的错误处理