Декодер Swift 4 JSON с вложенными данными

Это структура данных (обновлено):

    {
  "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"
        }
      }
    ]
  }
}

Я попробовал ответ здесь: Ожидается декодирование Array‹Any › но вместо этого нашел словарь

Но не могу заставить его работать. Я продолжаю получать и ошибаться в этой строке:

let root = try JSONDecoder().decode(Root.self, from: data)

Мои модели (обновлено):

 struct Root: Decodable {
    let arrivals: Arrivals
}

struct Arrivals: Decodable {
    let all: All
}

struct All: Decodable {
    let trains: [Train]
}

Ошибка:

▿ 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

person kakubei    schedule 18.10.2018    source источник
comment
Где эквивалент ключа departures в вашем struct ? Это должен быть ключ Root.   -  person Larme    schedule 18.10.2018
comment
@matt Я не показывал настоящий JSON, потому что он очень длинный. я просто обрезал конец   -  person kakubei    schedule 18.10.2018
comment
Ааа, неправильный образец @larme! Извинения. Будет обновляться с правильным.   -  person kakubei    schedule 18.10.2018
comment
@matt, да, извини, приятель, взял не тот образец.   -  person kakubei    schedule 18.10.2018


Ответы (1)


«Я пробовал ответить здесь: Ожидается декодирование массива, но вместо этого нашел словарь

Да, но ваше сообщение об ошибке прямо противоположное. Потратив немного времени на прочтение сообщения об ошибке, мы видим, что оно совершенно ясное и очевидно правильное.

В вашей структуре прибытия вы говорите

let all: All

Но значение ключа "all" в JSON — это массив! Таким образом, тип здесь должен быть массивом чего-то. В частности, это должен быть массив поездов.

let all: [Train]

И теперь вы можете удалить свою структуру All, которая никогда не была правильной.

Пример (работает с показанным вами JSON):

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"
person matt    schedule 18.10.2018
comment
Да, я тоже так пробовал. Но это не то, о чем говорит ошибка. Позвольте мне обновить последние значения. Ошибка говорит, что arrivals равно nil - person kakubei; 18.10.2018
comment
Тем не менее, мой ответ абсолютно правильный для вопроса, который вы задали. - person matt; 18.10.2018
comment
Мой ответ по-прежнему кажется мне правильным. Удалите свою структуру All и сделайте то, что я сказал. - person matt; 18.10.2018
comment
Извините, @matt, но это не так, парсер даже не заходит так далеко. Посмотрите на ошибку выше в лучшем формате. - person kakubei; 18.10.2018
comment
Это говорит именно то, что я сказал. Он декодирует прибытия, но не может декодировать все. Вы не сделали того, что я сказал сделать, поэтому, конечно, это не работает. - person matt; 18.10.2018
comment
Почти уверен, что Мэтт прав. Глядя на json, что вы найдете для значения ключа «все», вы найдете массив поездов. ключевые поезда нигде не присутствуют в json, но это ваш ключ кодирования для всей структуры. - person Augie; 18.10.2018
comment
Добавлено доказательство того, что мой ответ правильный, учитывая предоставленный JSON. - person matt; 18.10.2018