JSON Codable - 如何处理 [Any]?

JSON Codable - What to do with [Any]?

我有一个具有以下结构的 JSON:

         "properties":[

            {

               "name":"Quality",
               "values":[],
               "displayMode":0,
               "type":6
            },
            {

               "name":"Armour",
               "values":[],
               "displayMode":0,
               "type":16
            },
            {

               "name":"Evasion Rating",
               "values":[],
               "displayMode":0,
               "type":17
            }
         ]

API 始终返回 "value" 的数组,第一个元素是 String,第二个元素是 Int

    "values":[

                  [
                     "+26%",
                     1
                  ]

               ],

到目前为止,我是这样映射 JSON 的:

struct Properties: Codable {
    var name: String
    var values: [Any]
    var displayMode: Int
    var type: Int
}

此时 Xcode 抱怨,因为 Type 'Properties' does not conform to protocol 'Decodable'

所以,我知道 Any 不符合 codable 但问题是我不知道如何将此 [Any] 转换成 Swift 可以与...一起工作

有人可以分享解决方案的提示吗?

非常感谢:)

在自定义 init(from:) 中解码时,您需要为此使用未加密的容器。

如果您知道总是有一个字符串后跟一个整数,您可以像这样定义值的结构

struct Value: Decodable {
    let string: String?
    let integer: Int?

    init(from decoder: Decoder) throws {
        var container = try decoder.unkeyedContainer()
        string = try container.decodeIfPresent(String.self)
        integer = try container.decodeIfPresent(Int.self)
    }
 }

如果可以有更多元素,您可以改用循环

struct Value: Decodable {
    let strings: [String]
    let integers: [Int]

    init(from decoder: Decoder) throws {
        var container = try decoder.unkeyedContainer()
        var strings = [String]()
        var integers = [Int]()

        while !container.isAtEnd {
            do {
                let string = try container.decode(String.self)
                strings.append(string)
            } catch {
                let integer = try container.decode(Int.self)
                integers.append(integer)
            }
        }
        self.integers = integers
        self.strings = strings
    }
}