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."
CodePudding user response:
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))
}