Быстрое декодирование JSON от Amadeus - PullRequest
0 голосов
/ 13 февраля 2020

У меня проблема с декодированием JSON из API. Я получаю JSON:

{
  "meta": {
    "count": 1,
    "links": {
      "self": "https://test.api.amadeus.com/v1/reference-data/locations?subType=AIRPORT&keyword=barcel&sort=analytics.travelers.score&view=LIGHT&page%5Boffset%5D=0&page%5Blimit%5D=10"
    }
  },
  "data": [
    {
      "type": "location",
      "subType": "AIRPORT",
      "name": "AIRPORT",
      "detailedName": "BARCELONA/ES:AIRPORT",
      "id": "ABCN",
      "self": {
        "href": "https://test.api.amadeus.com/v1/reference-data/locations/ABCN",
        "methods": [
          "GET"
        ]
      },
      "iataCode": "BCN",
      "address": {
        "cityName": "BARCELONA",
        "countryName": "SPAIN"
      }
    }
  ]
}

Мой код выглядит следующим образом:

struct Airport: Decodable {
    let meta: MetaAirport
    let data: AirportInfo
}
struct Address: Decodable{
    let countryName: String
    let cityName: String
}

struct AirportInfo: Decodable{

    let address: Address
    let subType: String
    let id: String
    let type: String
     let detailedName: String
     let name: String
     let iataCode: String

}

struct MetaAirport : Decodable{
    let count: Int
    let links: Links
}

struct Links : Decodable{
    let info: String

    private enum CodingKeys : String, CodingKey {
           case info = "self"
       }
}

Я пытаюсь декодировать json с помощью JSONDecoder для объекта AirportInfo

              do {
                let airport = try JSONDecoder().decode(Airport.self, from: data!)
                    print(airport.data.name)
                }
                catch let err {
                    print(err)
                }

Я получаю сообщение об ошибке

typeMismatch (Swift.Dictionary, Swift.DecodingError.Context (codingPath: [CodingKeys (stringValue: "data", intValue: nil)], debugDescription: "Ожидается декодировать словарь, но вместо этого нашел массив. ", underError: nil))

Что я делаю не так?

Ответы [ 3 ]

0 голосов
/ 13 февраля 2020

Я вижу, что вы отредактировали свой вопрос из оригинала, поэтому трудно правильно определить в данный момент времени, в чем проблема.

Однако , Codable - это прекрасно, и одним из простых способов для вас является создание вашего объекта понемногу. Не требуется, чтобы объект идентично представлял ваш JSON IF , который вы делаете необязательным. Поэтому при отладке такого рода проблем сделайте разные свойства необязательными и посмотрите, что было проанализировано. Это позволит вам постепенно определять, где вы делаете что-то не так, не вызывая сбоев и сохраняя правильно отформатированные части.

Кроме того, профессиональный совет: если вы планируете сохранить этот код для чего-то большего, чем 1 неделю, прекратите использовать принудительную распаковку ! и привыкните к правильной обработке опций. В противном случае эту привычку трудно прекратить, и другие будут ненавидеть созданный вами код;)

0 голосов
/ 13 февраля 2020

Ваша модель должна быть такой для разбора

struct DataModel: Codable {
    let meta: Meta?
    let data: [Datum]?
}

struct Datum: Codable {
    let type, subType, name, detailedName: String?
    let id: String?
    let datumSelf: SelfClass?
    let iataCode: String?
    let address: Address?

    enum CodingKeys: String, CodingKey {
        case type, subType, name, detailedName, id
        case datumSelf = "self"
        case iataCode, address
    }
}

struct Address: Codable {
    let cityName, countryName: String?
}

struct SelfClass: Codable {
    let href: String?
    let methods: [String]?
}

struct Meta: Codable {
    let count: Int?
    let links: Links?
}

struct Links: Codable {
    let linksSelf: String?

    enum CodingKeys: String, CodingKey {
        case linksSelf = "self"
    }
}
0 голосов
/ 13 февраля 2020

В json данных адрес является объектом. Измените свой код:

let address: [Address] -> let address: Address
...