使用结构可解码swift 4/5在IOS中解码具有不同数据类型的json数组数据

问题描述 投票:0回答:1

我已经尝试过使用它来构造和解码结构,但只有在所有数据类型都与定义的相同时,它才有效

例如,下面的代码可以正常工作

{"key1": "stringValue", "key2": intValue, "key3": ["stringData1", "stringData2", "stringData3"]}
struct User: Decodable               
{
    var key1: String
    var key2: Int
    var key3: [String]
}

let decoder = JSONDecoder()
let decodedJsonData = try decoder.decode(User.self, from: data)
print(decodedJsonData)

如果key3包含不同的数据类型,我该怎么办?

{"key1": "stringValue", "key2": intValue, "key3": ["stringData1", IntData, FloatData]}
ios swift json-deserialization codable decodable
1个回答
2
投票

使用具有关联值的枚举:

struct User: Codable {
    let command, updated: Int
    let data: [Datum]
}

enum Datum: Codable {
    case double(Double)
    case string(String)

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

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

要获得data中的各个值,请使用如下代码:

let json = """
    {"command": 1, "updated": 2, "data": ["stringData1", 42, 43]}
    """.data(using: .utf8)

do {
    let user = try JSONDecoder().decode(User.self, from: json!)

    for d in user.data {
        switch d {
        case .string(let str): print("String value: \(str)")
        case .double(let dbl): print("Double value: \(dbl)")
        }
    }
} catch {
    print(error)
}
© www.soinside.com 2019 - 2024. All rights reserved.