1

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
4
  • Where is the departures key equivalent in your struct ? It's should be a key of Root. Commented Oct 18, 2018 at 14:20
  • @matt I didn't show the real JSON because it's very long. I just truncated the end Commented Oct 18, 2018 at 14:57
  • Ahh, wrong sample @larme! Apologies. Will update with the right one. Commented Oct 18, 2018 at 15:02
  • @matt, yeah sorry mate, got the wrong sample. Commented Oct 18, 2018 at 15:07

1 Answer 1

2

"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"
Sign up to request clarification or add additional context in comments.

7 Comments

Yeah, I've tried that as well. But that's not what the error is referring to. Let me update with the latest values. The error is saying arrivals is nil
However, my answer is absolutely right for the question you asked.
My answer still seems right to me. Delete your All struct and do what I said.
Sorry @matt, but it isn't, the parser doesn't even get that far. Look at the error above better formatted.
It says just what I said. It decodes arrivals but then can’t decode all. You have not done what I said to do so of course it isn’t working.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.