skip to Main Content

I have this JSON coming from a server…

{
  "cars": [
    {
      "name": "Ferrari",
      "price": "100"
    },
    {
      "name": "Lamborghini",
      "price": "200"
    },
    {
      "name": "Ford Pinto",
      "price": "1"
    }
  ]
}

This JSON is a dictionary called cars that contains an array of cars, right?

Then I have this struct…

struct Cars: Codable {
    let cars: [Car]
}


struct Car: Codable, Hashable, Identifiable {
    let id = UUID()
    let name: String
    let price: String
}

and I decode the JSON using this:

let (data, _) = try await urlSession.data(from: url)
let result = try JSONDecoder().decode(Cars.self, from: data)
let listOfCars = result.cars

This is something I don’t understand.

in result.cars, cars is a property of result that was declared as an array in the struct Cars. Not a dictionary.

I was expecting to access it using result["cars"].

Why is that?

2

Answers


  1. In your code here…

    let (data, _) = try await urlSession.data(from: url)
    let result = try JSONDecoder().decode(Cars.self, from: data)
    let listOfCars = result.cars
    

    result is an instance of the Struct Cars. Your set up code has told Swift how to translate from a JSON dictionary into your own Struct.

    So everything inside of result is accessed just like how you would access it in the following…

    let result = Cars(cars: [
      Car(name: "Ford", price: "£10,000")
    ])
    
    print(result.cars)
    

    The only difference is how you are creating it. Instead of using the init method like this you are using a JSON decode to decode some JSON into your custom type.

    Login or Signup to reply.
  2. As said in the comments and answers, it takes a result type according to your decode strategy. In your code result type is Cars not a dictionary. So you access the properties with using result.cars

    If you want something as dictionary instead, you need to decode it like

    let result = try decode.decode([String : [Car]].self, from: data)
    

    Now you can access them like a dictionar

    print(result["cars"]?.first?.name) // Optional("Ferrari")
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search