lpy
lpy

Reputation: 25

Use JSONDecoder in swift 4

I am using swift 4 xcode 9.2, I got the below error when using JSONDecoder.

typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array but found a dictionary instead.", underlyingError: nil))

class Hits: Codable { 
    let hits: [Hit] 

    init(hits: [Hit]) { 
       self.hits = hits 
    } 
}

class Hit: Codable { 
    let recipe: String 
    let uri: String 
    let label: String 
    let image: String 
    let source: String 
    let url: String 
    let shareAs: String 
    let yield: String 

    init(recipe: String, uri: String, label: String, image: String, source: String, url: String, shareAs: String, yield: String) {
        self.recipe = recipe 
        self.uri = uri 
        self.label = label 
        self.image = image 
        self.source = source 
        self.url = url 
        self.shareAs = shareAs 
        self.yield = yield
    }
}

func downloadJSON() { 
    guard let downloadURL = url else {return}   
    URLSession.shared.dataTask(with: downloadURL) { (data, urlResponse, error) in 
       guard let data = data, error == nil, urlResponse != nil else { print("Something is wrong"); return } 
       print("download completed") 
       do { 
          let decoder = JSONDecoder() 
          let foods = try decoder.decode([Hits].self, from: data)  
          print(foods) 
       } catch { 
          print(error) 
       } 
   }.resume()
}

Here is the JSON: https://api.edamam.com/search?q=chicken&app_id=110d8671&app_key=3f01522208d512f592625dfcd163ff5c&from=0&to=10

Upvotes: 1

Views: 1919

Answers (2)

vadian
vadian

Reputation: 285072

The error clears states that you are trying to decode an array but the actual type is a dictionary (single object).

Replace

let foods = try decoder.decode([Hits].self, from: data)

with

let foods = try decoder.decode(Hits.self, from: data)

And your classes (actually structs are sufficient) are

struct Recipe : Decodable {
    let uri : URL
    let label : String
    let image : URL
    let source : String
    let url : URL
    let shareAs : URL
    let yield : Double
    let calories, totalWeight, totalTime : Double
}

struct Hits: Decodable {
    let hits: [Hit]
}

struct Hit: Decodable {
    let recipe: Recipe
}

Upvotes: 2

Chris
Chris

Reputation: 8091

hits = try decoder.decode(Hits.self from: data)

Upvotes: 0

Related Questions