【问题标题】:Decodable structure of Google APIGoogle API 的可解码结构
【发布时间】:2019-04-24 00:20:20
【问题描述】:

我尝试从 Google API 服务器解码数据,但他们总是遇到类似

的错误

typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "rows", intValue: nil), _JSONKey(stringValue: "索引 0", intValue: 0), CodingKeys(stringValue: "elements", intValue: nil), _JSONKey(stringValue: "索引 0", intValue: 0), CodingKeys(stringValue: "distance", intValue: nil)], debugDescription: "预期解码 Array 但找到了字典。", 底层错误:无))

我没有实现这个的任何变体

{
    "destination_addresses": [
        "Абая-Саина, просп. Абая, Алматы, Казахстан"
    ],
    "origin_addresses": [
        "г. Алматы, ул. Джандосова, 6, уг. ул. Манаса, Алматы, Казахстан"
    ],
    "rows": [
        {
            "elements": [
                {
                    "distance": {
                        "text": "7,2 км",
                        "value": 7241
                    },
                    "duration": {
                        "text": "16 мин.",
                        "value": 980
                    },
                    "status": "OK"
                }
            ]
        }
    ],
    "status": "OK"
}

这是我的关键结构

struct Distance:Codable {
    var destination_addresses  : [String]?
    var origin_addresses : [String]?
    var rows : [row]?
    var status : String?
    enum CodingKeys:String,CodingKey{
        case destination_addresses = "destination_addresses"
        case origin_addresses = "origin_addresses"
        case rows = "rows"
        case status = "status"
    }
}

struct row:Codable {
    var elements : [elements]?
    enum CodingKeys:String,CodingKey {
        case elements = "elements"
    }
}
struct elements:Codable {
    var distance : [distance]?
    var duration : [duration]?
    var status : String?
    enum CodingKeys:String,CodingKey {
        case distance = "distance"
        case duration = "duration"
        case status = "status"
    }
}
struct distance:Codable {
    var text : String?
    var value : Int?
    enum CodingKeys:String,CodingKey {
        case text = "text"
        case value = "value"
    }
}
struct duration:Codable {
    var text : String?
    var value : Int?
    enum CodingKeys:String,CodingKey {
        case text = "text"
        case value = "value"
    }
}

我的解码

        let root = try decoder.decode(Distance.self, from: data)

【问题讨论】:

  • 如果 JSON 中的名称与 Codable 类型中的名称匹配,则无需定义 CodingKey 类型。如果枚举的大小写名称与 String 原始值匹配字符串值,则无需将其写下来。
  • Swift 命名约定以大写字母开头的结构命名
  • This Website 从您的 JSON 生成所需的 Swift 代码。可能会有所帮助

标签: json swift decodable


【解决方案1】:

你可以试试

struct Root: Codable {
    let destinationAddresses, originAddresses: [String]
    let rows: [Row]
    let status: String

    enum CodingKeys: String, CodingKey {
        case destinationAddresses = "destination_addresses"
        case originAddresses = "origin_addresses"
        case rows, status
    }
}

struct Row: Codable {
    let elements: [Element]
}

struct Element: Codable {
    let distance, duration: Distance // your problem is here
    let status: String
}

struct Distance: Codable {
    let text: String
    let value: Int
}

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

作为

var distance : [distance]?
var duration : [duration]?

是字典而不是数组

也不需要为相同的内容创建 2 个 strcut distanceduration 只需 1 个就足够了,因为关键在于仅更改密钥

此外,如果您不更改键名,请不要在结构中使用enum CodingKeys: String, CodingKey {,因为这将无用

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2011-01-06
  • 1970-01-01
  • 2021-06-11
  • 2018-11-28
  • 1970-01-01
  • 2015-10-06
  • 2021-04-15
  • 1970-01-01
相关资源
最近更新 更多