Search code examples
jsonswift4decoderxcode9-beta

SWIFT 4, Xcode 9, JSON DECODER


I'm pretty stuck now. I'm attempting to PARS a JSON RETURN for just the year make make and model. It's buried in an array of dictionaries, and the decoder is having a hard time pulling them out. What am I doing wrong?

public struct Page: Decodable {
let Count: Int
let Message: String
let SearchCriteria: String
let Results: [car]}


public struct car: Decodable {
let ModelYear: String
let Make: String
let Model: String
let VIN: String}


        let session = URLSession.shared
        let components = NSURLComponents()
        components.scheme  = "https"
        components.host = "vpic.nhtsa.dot.gov"
        components.path = "/api/vehicles/decodevinvaluesextended/\(VIN)"
        components.queryItems = [NSURLQueryItem]() as [URLQueryItem]
        let queryItem1 = NSURLQueryItem(name: "Format", value: "json")
        components.queryItems!.append(queryItem1 as URLQueryItem)
        print(components.url!)

 let task =  session.dataTask(with: components.url!, completionHandler: {(data, response, error) in
          guard let data = data else { return }
            do
                {
                    //let Result = try JSONDecoder().decode(Page.self, from: data)
                   // let PageResult = try JSONDecoder().decode(Page.self, from: data)
                    let json = try JSONDecoder().decode(Page.self, from: data)
                    let Results = json.Results;


                  print(Results)

Solution

  • First of all it's highly recommended to conform to the Swift naming convention that variable names start with a lowercase and structs start with a capital letter

    public struct Page: Decodable {
    
        private enum CodingKeys : String, CodingKey {
            case count = "Count", message = "Message", searchCriteria = "SearchCriteria", cars = "Results"
        }
    
        let count: Int
        let message: String
        let searchCriteria: String
        let cars: [Car]
    }
    
    
    public struct Car: Decodable {
    
        private enum CodingKeys : String, CodingKey {
            case modelYear = "ModelYear", make = "Make", model = "Model", VIN
        }
    
        let modelYear: String
        let make: String
        let model: String
        let VIN: String
    }
    

    The cars array is in the variable result. This code prints all values

    let result = try JSONDecoder().decode(Page.self, from: data)
    for car in result.cars {
         print("Make: \(car.make), model: \(car.model), year: \(car.modelYear), VIN: \(car.VIN)")
    }