【问题标题】:Swift Decoding JSON from Amadeus来自 Amadeus 的 Swift 解码 JSON
【发布时间】:2020-02-13 08:59:11
【问题描述】:

我在从 API 解码 JSON 时遇到问题。 我得到 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"
       }
}

我正在尝试在 AirportInfo 对象上使用 JSONDecoder 解码 json

              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: "期望解码字典,但找到了一个数组。",underlyingError: nil ))

我做错了什么?

【问题讨论】:

  • 现在——在编辑之后——情况完全不同了。请阅读错误和 JSON。 data 显然是一个数组。
  • 我编辑我的代码。我知道我必须在机场结构让数据:[AirportInfo]
  • 错误提示你将data属性的定义改为let data: [AirportInfo]

标签: swift decodable jsondecoder


【解决方案1】:

在json数据中,地址是一个对象。更改您的代码:

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

【讨论】:

    【解决方案2】:

    你的模型应该是这样解析的

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

    【讨论】:

      【解决方案3】:

      我看到您已根据原始问题编辑了您的问题,因此很难在给定时刻正确识别问题所在。

      然而,Codable 非常棒,一种简单的解决方法就是一点一点地构建你的对象。不需要一个对象以相同的方式表示您的 JSON IF,您可以将其设为可选。因此,在调试此类问题时,将不同的属性设为可选,然后查看解析了什么。这将使您能够一点一点地确定您做错了什么,而不会导致崩溃并保持正确格式的部分。

      另外,专业提示:如果您打算将此代码保留超过 1 周,请停止使用强制解包 ! 并习惯于正确处理选项。否则这是一个很难改掉的习惯,其他人会讨厌你创建的代码;)

      【讨论】:

      • @oyasumi,请查看您的问题的更新答案。我认为学习如何使用 Codable 通常比试图在积极开发的结构中找到特定错误更有价值
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-20
      • 1970-01-01
      • 1970-01-01
      • 2018-09-10
      • 1970-01-01
      • 2014-05-24
      相关资源
      最近更新 更多