Декодируемая структура Google API - PullRequest
0 голосов
/ 21 ноября 2018

Я пытаюсь декодировать данные с сервера Google API, и они всегда получают ошибку mo, например

typeMismatch (Swift.Array, Swift.DecodingError.Context (codingPath: [CodingKeys (stringValue: ")row ", 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: "Ожидается декодировать массив, но вместо этого найден словарь.", underError: 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)

1 Ответ

0 голосов
/ 21 ноября 2018

Вы можете попробовать

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 строки дляодного и того же содержимого distance и duration достаточно только 1, так как смысл в изменении только ключа

Кроме того, не используйте enum CodingKeys: String, CodingKey { в структуре, если вы не измените имена ключей, как это было быбыть бесполезным

...