Google API 的可解码结构

Decodable structure of Google API

我尝试解码来自 Google API 服务器的数据,但他们总是遇到

这样的错误

typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "rows", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "elements", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "distance", intValue: nil)], debugDescription: "Expected to decode Array but found a dictionary instead.", underlyingError: nil))

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

{
    "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)

你可以试试

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 个 strcuts distanceduration 只需 1 个就足够了,因为关键是只更改密钥

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