如何在 swift 中使用 JSONDecoder 输入调整?

Posted

技术标签:

【中文标题】如何在 swift 中使用 JSONDecoder 输入调整?【英文标题】:How do type adjust uing JSONDecoder in swift? 【发布时间】: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。

【问题讨论】:

Swift 4 Codable - Bool or String values的可能重复 @Larme 不是很近。我想解码我的应用程序的所有模型,而不是特殊模型。如果我喜欢这样,这意味着我要为每个模型编写大量模板代码。也许这是一种选择。 如果您的模型遇到这样的情况,那么您别无选择,没有其他方法可以解码可能有 2 种不同类型的属性 其实@qiushuitian这是复制品。 【参考方案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)
    

【讨论】:

以上是关于如何在 swift 中使用 JSONDecoder 输入调整?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 swift 4.1 和 xcode 9.3 中使用 JSONDecoder 解码嵌套的 JSON 数组和对象?

Swift 的 JSONDecoder 在 JSON 字符串中有多种日期格式?

如何准备 API 响应以在 swift 中与 jsonDecoder 一起使用

使用 JSONDecoder Swift 解码具有整数值的字符串键 [关闭]

Swift 5:如何从 JSONDecoder().decode 获取数据?

在 Swift 4 中使用新的 JSONDecoder 协议时,我得到“无法读取数据,因为它的格式不正确。”错误