Swift Json 可解码数据结构,单个数组中的不同值

Swift Json Decodable data structure, varying values in single array

我在做什么

"meta_data": [
        {
            "id": 4116,
            "key": "_wcf_frm_created",
            "value": ""
        },
        {
            "id": 4117,
            "key": "_wcf_custom_degin_checkbox",
            "value": ""
        },
        {
            "id": 4118,
            "key": "_wcf_frm_data",
            "value": {
                "1": {
                    "1": "",
                    "2": "",
                    "3": "chk_box"
                }
            }
        },
        {
            "id": 4142,
            "key": "_vendor_select",
            "value": "6484"
        },
        {
            "id": 4143,
            "key": "_vendor_percentage",
            "value": "100"
        },
        {
            "id": 4144,
            "key": "_vendor_pro_cat",
            "value": "Sushi"
        },
        {
            "id": 4156,
            "key": "slide_template",
            "value": "default"
        }
    ],
    "_links": {
        "self": [
            {
                "href": "https://xxxxxx.net/wp-json/wc/v3/products/6489"
            }
        ],
        "collection": [
            {
                "href": "https://xxxxxx.net/wp-json/wc/v3/products"
            }
        ]
    }

我目前拥有的

struct woocomerceProduct : Decodable, Encodable
{
    var meta_data : [Meta_data?]
    var _links : [_Links?]


}

    struct Meta_data : Decodable, Encodable
{
    var id : Int?
    var key : String?
    var value : String?
}
   struct One : Decodable, Encodable
{
        var one : String?
        var two : String?
        var three : String?
}

struct _Links : Decodable, Encodable
{
    var SELF : [String?]
    var collectio : [String?]
}

好的,下面是问题。 1. id 4118.value 从String 到obj,这部分如何编码? 2.它还用了一个变量字符串“1”,“2”...我不能用整数作为变量,所以我拼出来了?应该可以。 3. 这里的值是 self,我不能使用变量 self 因为它会认为它是一个 self 属性。所以我只是把它大写了。

我看了这个,我认为这与我需要做的类似,但由于这是一个对象和一个字符串之间的东西,我不确定我需要在这里编写什么代码。

太多不必要的可选项,太多不必要的下划线字符。

  1. 要解码两种不同的类型,enum 与关联类型是合理的。
  2. 代码解码字典[String:[String:String]]
  3. 要映射不适当的键,请提供 CodingKeys。

struct WoocomerceProduct : Decodable {
    let metaData : [Meta]
    let links : Links

    private enum CodingKeys : String, CodingKey { case metaData  = "meta_data", links = "_links" }
}

struct Meta : Decodable {
    let id : Int
    let key : String
    let value : StringOrDictionary
}

struct Links : Decodable {
    let myself : [URLType]
    let collection : [URLType]

    private enum CodingKeys : String, CodingKey { case myself  = "self", collection }
}

struct URLType : Decodable {
    let href : URL
}


enum StringOrDictionary : Decodable {
    case string(String), dictionary([String:[String:String]])

    init(from decoder : Decoder) throws
    {
        let container = try decoder.singleValueContainer()
        do {
            let stringData = try container.decode(String.self)
            self = .string(stringData)
        } catch DecodingError.typeMismatch {
            let dictionaryData = try container.decode([String:[String:String]].self)
            self = .dictionary(dictionaryData)
        }
    }
}

试试这个 link 将您的 json 转换成 Codable 模型 link

    import Foundation

// MARK: - Welcome
struct Welcome: Codable {
    let metaData: [MetaDatum]
    let links: Links

    enum CodingKeys: String, CodingKey {
        case metaData = "meta_data"
        case links = "_links"
    }
}

// MARK: - Links
struct Links: Codable {
    let linksSelf, collection: [Collection]

    enum CodingKeys: String, CodingKey {
        case linksSelf = "self"
        case collection
    }
}

// MARK: - Collection
struct Collection: Codable {
    let href: String
}

// MARK: - MetaDatum
struct MetaDatum: Codable {
    let id: Int
    let key: String
    let value: ValueUnion
}

enum ValueUnion: Codable {
    case string(String)
    case valueClass(ValueClass)

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let x = try? container.decode(String.self) {
            self = .string(x)
            return
        }
        if let x = try? container.decode(ValueClass.self) {
            self = .valueClass(x)
            return
        }
        throw DecodingError.typeMismatch(ValueUnion.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for ValueUnion"))
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .string(let x):
            try container.encode(x)
        case .valueClass(let x):
            try container.encode(x)
        }
    }
}

// MARK: - ValueClass
struct ValueClass: Codable {
    let the1: [String: String]

    enum CodingKeys: String, CodingKey {
        case the1 = "1"
    }
}