ios - 使用 struct decodable swift 在 IOS 中解码具有不同数据类型的 json 数组数据 4/5

标签 ios swift json-deserialization codable decodable

我已经尝试构建结构并使用它进行解码,但只有当所有数据类型都与定义的相同时它才有效

例如下面的代码工作正常:

{"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]}

最佳答案

使用具有关联值的枚举:

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)
}

关于ios - 使用 struct decodable swift 在 IOS 中解码具有不同数据类型的 json 数组数据 4/5,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59433734/

相关文章:

ios - removeGestureRecognizer 方法

ios - SwiftUI 中的问题,Swift SignalR 客户端 WebSocket 关闭。代码 : 1000

ios - 如何在 iOS 上的按钮中显示带下划线的文本?

ios - 使用 Swift 自定义 UIStoryboard

ios - 如何获取authenticationToken放入pass.json

ios - 用于单元测试的核心数据临时数据库

ios - 如何将视频数据转换为NSURL

c# - 如何将 JSON 反序列化为从 RestSharp 调用 API 返回的对象数组?

php - 在 PHP 中检查字符串是否为 JSON 的最快方法?

java - 从父节点创建的 Jackson 引用对象