Search code examples
iosjsonswiftparsingdecodable

Fetching and parsing JSON


I’m having a really hard time fetching and parsing the following JSON. I can't even fetch the data from given url, even less parse it using my data Model "Car". Any help is more than welcomed!

JSON

{
   "cars":[
      {
         "date_stolen":1604616183,
         "description":null,
         "body_colors":[
            "Black",
            "Blue"
         ],
         "id":"944846",
         "is_stock_img":false,
         "large_img":null,
         "location_found":null,
         "manufacturer_name":"Toyota",
         "external_id":null,
         "registry_name":null,
         "registry_url":null,
         "serial":"36-17-01012-xl09",
         "status":null,
         "stolen":true,
         "stolen_location":"Calgary - CA",
         "thumb":null,
         "title":"2017 Toyota Corolla ",
         "url":"https://cars.org/944846",
         "year":2017
      }
   ]
}
struct Car: Decodable {
        let cars: String
    }
var cars = [Car]()
fileprivate func fetchJSON() {
        let urlString = "someUrl…"
        guard let url = URL(string: urlString) else { return }
        URLSession.shared.dataTask(with: url) { (data, _, err) in
            DispatchQueue.main.async {
                if let err = err {
                    print("Failed to get data from url:", err)
                    return
                }
                
                guard let data = data else { return }
                
                do {
                    
                    let decoder = JSONDecoder()
                    
                    decoder.keyDecodingStrategy = .convertFromSnakeCase

                    print("DATA \n", data)
                    self.cars = try decoder.decode(Car.self, from: data)
                    
                    print("---> ", data)
                    
                } catch let jsonErr {
                    print("Failed to decode:", jsonErr)
                }
            }
        }.resume()
    }

Solution

  • You Car model does not represent you json structure.

    You're looking for something like this :

    struct CarsResponse: Decodable {
        let cars: [CarDTO]
    }
    
    struct CarDTO: Decodable {
        let id: String
        let isStockImg: Bool
        // And so on
    }
    

    Then just write :

    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let carResponse = try decoder.decode(CarsResponse.self, from: data)
    

    You will access your cars by writing

    let cars: [CarDTO] = carResponse.cars