Gets error when getting data from API in Swift: "Expected to decode Dictionary<String, Any> but found an array instead."

I am new to swift, and currently trying to get data from this API, but this error keeps popping up in the log:

"Expected to decode Dictionary<String, Any> but found an array instead.".

Pls help.
See example of the array from website as a comment in the lower part of the code snippet.

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) {
        let task = 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 fruits:FruitsData?
            do {
                fruits = try JSONDecoder().decode(FruitsData.self, from: data)
            }
            catch {
                print(String(describing: error))
            }
            
            guard let json = fruits else {
                return
            }
            
            print(json.fruits)
            
        })
        
        task.resume()
    }


}

struct FruitsData: Codable {
    let fruits: [Fruit]
}

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
}
 [
    {
     "genus": "Malus",
     "name": "Apple",
     "id": 6,
     "family": "Rosaceae",
     "order": "Rosales",
     "nutritions": {
         "carbohydrates": 11.4,
         "protein": 0.3,
         "fat": 0.4,
         "calories": 52,
         "sugar": 10.3
        }
    }, {
     "genus": "Prunus",
     "name": "Apricot",
     "id": 35,
     "family": "Rosaceae",
     "order": "Rosales",
     "nutritions": {
         "carbohydrates": 3.9,
         "protein": 0.5,
         "fat": 0.1,
         "calories": 15,
         "sugar": 3.2
        }
    }
 ]

I tried running the code, expected to get the array from API printed, instead I got printed this error: "Expected to decode Dictionary<String, Any> but found an array instead."

>Solution :

The JSON data contains a list of fruits (an array), but you try to decode a FruitsData. It would expect the JSON top-level to look like this:

{
    "fruits": [ … ]
}

Instead, you need to decode an array of fruits directly like this:

var fruits:[Fruit]?
do {
    fruits = try JSONDecoder().decode([Fruit].self, from: data)
}
catch {
    print(String(describing: error))
}

Leave a Reply