I expect the result to be a dictionary but it is accessed like a property… why?
Problem Description:
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?
Solution – 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.
Solution – 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")