Reputation: 5400
This is the data structure (updated):
{
"date": "2018-10-18",
"time_of_day": "16:00",
"request_time": "2018-10-18T16:00:27+01:00",
"station_name": "London Waterloo",
"station_code": "WAT",
"arrivals": {
"all": [
{
"mode": "train",
"service": "24673605",
"train_uid": "W12378",
"platform": "10",
"operator": "SW",
"operator_name": "South Western Railway",
"aimed_departure_time": null,
"aimed_arrival_time": "05:18",
"aimed_pass_time": null,
"origin_name": "Guildford",
"destination_name": "London Waterloo",
"source": "ATOC",
"category": "OO",
"service_timetable": {
"id": "https://transportapi.com/v3/uk/train/service/train_uid:W12378/2018-10-18/timetable.json?app_id=80b56d0a&app_key=b44a5870830959a7a961fdbb65f9dc13"
}
},
{
"mode": "train",
"service": "24671505",
"train_uid": "W14110",
"platform": "1",
"operator": "SW",
"operator_name": "South Western Railway",
"aimed_departure_time": null,
"aimed_arrival_time": "05:35",
"aimed_pass_time": null,
"origin_name": "Twickenham",
"destination_name": "London Waterloo",
"source": "ATOC",
"category": "OO",
"service_timetable": {
"id": "https://transportapi.com/v3/uk/train/service/train_uid:W14110/2018-10-18/timetable.json?app_id=80b56d0a&app_key=b44a5870830959a7a961fdbb65f9dc13"
}
},
{
"mode": "train",
"service": "24671105",
"train_uid": "W14764",
"platform": "15",
"operator": "SW",
"operator_name": "South Western Railway",
"aimed_departure_time": null,
"aimed_arrival_time": "05:41",
"aimed_pass_time": null,
"origin_name": "Staines",
"destination_name": "London Waterloo",
"source": "ATOC",
"category": "OO",
"service_timetable": {
"id": "https://transportapi.com/v3/uk/train/service/train_uid:W14764/2018-10-18/timetable.json?app_id=80b56d0a&app_key=b44a5870830959a7a961fdbb65f9dc13"
}
}
]
}
}
I've tried the answer here: Expected to decode Array<Any> but found a dictionary instead
But can't quite get it to work. I keep getting and error on this line:
let root = try JSONDecoder().decode(Root.self, from: data)
My models (updated):
struct Root: Decodable {
let arrivals: Arrivals
}
struct Arrivals: Decodable {
let all: All
}
struct All: Decodable {
let trains: [Train]
}
Error:
▿ DecodingError
▿ typeMismatch : 2 elements
- .0 : Swift.Dictionary<Swift.String, Any>
▿ .1 : Context
▿ codingPath : 2 elements
- 0 : CodingKeys(stringValue: "arrivals", intValue: nil)
- 1 : CodingKeys(stringValue: "all", intValue: nil)
- debugDescription : "Expected to decode Dictionary<String, Any> but found an array instead."
- underlyingError : nil
Upvotes: 1
Views: 446
Reputation: 534950
"I've tried the answer here: Expected to decode Array but found a dictionary instead
Yes, but your error message is just the opposite. Taking a moment to read the error message, we can see that it is perfectly clear and obviously right.
In your Arrivals struct, you are saying
let all: All
But the value of the "all"
key in the JSON is an array! So the type here must be an array of something. In particular it should be an array of trains.
let all: [Train]
And now you can delete your All struct, which was never right.
Example (running against the JSON you showed):
struct Root: Decodable {
let arrivals: Arrivals
}
struct Arrivals: Decodable {
let all: [Train]
}
struct Train: Decodable {
}
let data = json.data(using: .utf8)!
if let root = try? JSONDecoder().decode(Root.self, from: data) {
print("got", String(root.arrivals.all.count), "trains")
}
// "got 3 trains"
Upvotes: 2