使用 Codable 时,如何在枚举 CodingKeys 中指定多个类型进行解码?

How do I specify more than one type to decode in the enum CodingKeys when using Codable?

我有一个 struct 类型,它列出了必须从 JSON 解码的不同类型,但我找不到任何关于如何在我的 enum 中指定多个类型的信息CodingKeys。在最里面的字典中,有时一对 key:value 将是 [String:String] 而另一对 key:value 将是 [String:Int]

我试过在下面的代码片段中仅指定 StringCodingKey,但 Xcode 报告了 2 条错误消息。

struct JSONSiteData : Codable {
    let destinationAddresses : [String]
    let originAddresses : [String]
    let rows : [    [String : [[String:[[String: [String:Any]]]]]]      ]
    let status : String
}

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

我从 Xcode;

收到以下错误消息
Type 'JSONSiteData' does not conform to protocol 'Decodable'
Type 'JSONSiteData' does not conform to protocol 'Encodable'

这是我的 JSON;

{
    "destination_addresses": [
        "1 Dunwell Ln, Bolam, Darlington DL2 2UW, UK",
        "Unnamed Road, Newton Aycliffe DL5 6QZ, UK",
        "Preston Manor Farm, Preston le Skerne, Newton Aycliffe DL5 6JH, United Kingdom",
        "6 Middridge Farms, Middridge, Newton Aycliffe DL5 7JQ, UK",
        "1 The Gardens, Hunwick, Crook DL15 0XW, UK"
    ],
    "origin_addresses": [
        "42 Drovers Way, Dunstable LU6 1AW, UK"
    ],
    "rows": [
        {
            "elements": [
                {
                    "distance": {
                        "text": "220 mi",
                        "value": 353731
                    },
                    "duration": {
                        "text": "3 hours 45 mins",
                        "value": 13475
                    },
                    "status": "OK"
                },
                {
                    "distance": {
                        "text": "222 mi",
                        "value": 356696
                    },
                    "duration": {
                        "text": "3 hours 45 mins",
                        "value": 13471
                    },
                    "status": "OK"
                },
                {
                    "distance": {
                        "text": "222 mi",
                        "value": 358053
                    },
                    "duration": {
                        "text": "3 hours 46 mins",
                        "value": 13545
                    },
                    "status": "OK"
                },
                {
                    "distance": {
                        "text": "225 mi",
                        "value": 361421
                    },
                    "duration": {
                        "text": "3 hours 49 mins",
                        "value": 13768
                    },
                    "status": "OK"
                },
                {
                    "distance": {
                        "text": "229 mi",
                        "value": 369280
                    },
                    "duration": {
                        "text": "3 hours 57 mins",
                        "value": 14238
                    },
                    "status": "OK"
                }
            ]
        }
    ],
    "status": "OK"
}

Codable而言,没有不同的类型。

解码这些结构

struct JSONSiteData : Decodable {
    let destinationAddresses : [String]
    let originAddresses : [String]
    let rows : [Row]
    let status : String
}

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

struct Element : Decodable {
    let distance : Item
    let duration : Item
    let status : String
}

struct Item : Decodable {
    let text : String
    let value : Int
}

你可以试试这个,

// To parse the JSON, add this file to your project and do:
//
//   let jsonSiteData = try? newJSONDecoder().decode(JSONSiteData.self, from: jsonData)

import Foundation

struct JSONSiteData: 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
    let status: String
}

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

参考此 link 从 JSON 字符串生成模型。 https://app.quicktype.io/