解码Json Swift 4 Codable Type Any

时间:2018-03-26 14:32:30

标签: json swift swift4 codable decodable

嘿伙计我解码时遇到问题。我有一个看起来像这样的Json:

"data": [
            [
                DoubleValue,
                DoubleValue,
                DoubleValue,
                DoubleValue,
                DoubleValue,
                "",
                ""
            ],
            [
                DoubleValue,
                DoubleValue,
                DoubleValue,
                DoubleValue,
                DoubleValue,
                "",
                ""
            ],
            [
                DoubleValue,
                DoubleValue,
                DoubleValue,
                DoubleValue,
                DoubleValue,
                "",
                ""
            ]
]

所以我的建议是创建一个包含[[Any]]的let数据,但是这对Codable不起作用,[[Double]]不可用,因为如果值为空,api会发送空字符串并且我收到了一个typeMismatch错误。

有人建议如何解决这个问题吗?

我目前的Codable看起来像

public struct JsonData: Codable {

var data: [[Double?]] = []

enum JsonDataCodingKey: String, CodingKey {

    case data
}

public init(from decoder: Decoder) throws {

    let container = try decoder.container(keyedBy: JsonDataCodingKey.self)

    var nestedContainer = try container.nestedUnkeyedContainer(forKey: .data)
    while !nestedContainer.isAtEnd {

        var innerContainer = try nestedContainer.nestedUnkeyedContainer()
        var dataSet: [Double?] = []
        while !innerContainer.isAtEnd {
            let value = try innerContainer.decodeIfPresent(Double.self)
            dataSet.append(value)
        }
        data.append(dataSet)
    }
}

}

但是使用这段代码,如果空字符串出现,我会遇到typeMismatch的问题。 -.-我试图解决这个问题几个小时但是我没有得到解决方案:(

希望有人可以帮忙:)

1 个答案:

答案 0 :(得分:2)

您有一个选项是enum可以解码为DoubleString并解码其中的数组。

另一种选择是抓住typeMismatch错误并继续:

var dataSet = [Double]()
while !innerContainer.isAtEnd {
    do {
        dataSet.append(try innerContainer.decode(Double.self))
    } catch DecodingError.typeMismatch {
        // Throw away the value by decoding something which doesn't actually decode.
        struct Empty : Codable {}
        let _ = try innerContainer.decode(Empty.self)
    }
}

此代码会丢弃所有非Double值并删除Optional,但您可以保持Optional输入并插入nil而不是丢弃如果您愿意,可以使用这些值。