【问题标题】:How do type adjust uing JSONDecoder in swift?如何在 swift 中使用 JSONDecoder 输入调整?
【发布时间】:2018-07-17 08:04:37
【问题描述】:

我这样定义一个模型:

struct DMTest: Codable {
    var uid: Int
    var name: String?
}

然后像这样进行模型解码:

    let jsonStr = "{\"uid\":123,\"name\":\"haha\"}"
    let jsonData = jsonStr.data(using: .utf8)!

    do {
        let decoder = JSONDecoder()
        let result = try decoder.decode(DMTest.self, from:jsonData)
        XCGLogger.debug("result = \(result)")
    }catch {
        XCGLogger.debug("error")
    }

当 jsonStr 如下图时,效果很好:

{"uid":123,"name":"haha"}

当jsonStr如下图时,会抛出异常:

{"uid":"123","name":"haha"}

表示如果“uid”的类型不是适配器,则无法解码。但是有时候服务器的框架是弱类型的,可能会给我这样的脏数据,请问如何调整类型呢?

例如:我在模型中定义了 Int,如果服务器给了一些 String 类型的数据,我可以将其转换为 Int,则直接解码为 Int,否则抛出 ecxeption。

【问题讨论】:

  • @Larme 不是很近。我想解码我的应用程序的所有模型,而不是特殊模型。如果我喜欢这样,这意味着我要为每个模型编写大量模板代码。也许这是一种选择。
  • 如果您的模型遇到这样的情况,那么您别无选择,没有其他方法可以解码可能有 2 种不同类型的属性
  • 其实@qiushuitian这是复制品。

标签: ios json swift


【解决方案1】:

您可以定义自定义解析解决方案:

struct DMTest: Codable {
    enum CodingKeys: String, CodingKey {
        case uid, name
    }
    var uid: Int
    var name: String?

    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        if let stringUID = try? container.decode(String.self, forKey: .uid), let intUID = Int(stringUID) {
            uid = intUID
        } else if let intUID = try? container.decode(Int.self, forKey: .uid) {
            uid = intUID
        } else {
            uid = 0 // or throw error
        }
        name = try container.decodeIfPresent(String.self, forKey: .name)
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-19
    • 2019-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多