【问题标题】:Swift - Is there a way to differentiate between a field not being present or a field being nil/null when decoding an optional Codable valueSwift - 在解码可选的 Codable 值时,有没有办法区分字段不存在或字段为 nil/null
【发布时间】:2019-07-07 05:47:50
【问题描述】:

必要的功能

我正在修改系统以将当前未发送的 API 请求队列保存到 UserDefaults,以便在用户连接允许时重新发送。

由于一些补丁请求需要能够向 API 发送一个实际的 NULL 值(如果它是 nil 可选的,而不只是忽略该字段),这意味着我需要能够从默认值编码和解码 nil/NULL 值对于某些领域。

问题

我将编码面朝下,并且可以愉快地对请求进行编码以将 NULL 字段发送到服务器或将它们编码为默认值。但是,我的问题是,在解码已保存的未发送请求时,我找不到区分实际 Nil 值和字段不存在的方法。

我目前正在使用decodeIfPresent 解码我的字段(这些请求的所有字段都是可选的),如果该字段为空或如果该字段设置为 Nil/NULL,则返回 nil。显然,这不适用于可以显式设置为 Nil 的字段,因为我无法区分这两种情况。

问题

是否有任何我可以实现的解码方法来区分不存在的字段和实际设置为 nil 的字段?

【问题讨论】:

    标签: swift encoding decoding codable


    【解决方案1】:

    没有办法,但是你可以添加其他信息来知道

    struct Root : Codable {
    
        let code : Int?
        let codeExists:Bool?
    
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self) 
            code = try values.decodeIfPresent(Int.self, forKey: .code)
            codeExists =  values.contains(.code)
    
        }
    }
    

    根据文档decodeIfPresent

    如果容器没有与 key 关联的值,或者该值为 null,则此方法返回 nil。这些状态之间的区别可以通过 contains(_:) 调用来区分。

    所以解码

    let str = """
    {
      "code" : 12
    }
    """
    

    给予

    Root(code: Optional(12), codeExists: Optional(true))

    &&

    这个

    let str = """
    {
      "code" : null
    }
    """
    

    给予

    Root(code: nil, codeExists: Optional(true))

    还有这个

    let str = """
    {
    
    }
    """
    

    给予

    Root(code: nil, codeExists: Optional(false))

    【讨论】:

      猜你喜欢
      • 2018-07-18
      • 1970-01-01
      • 2022-08-11
      • 1970-01-01
      • 1970-01-01
      • 2011-03-16
      • 2015-05-15
      • 2018-08-03
      相关资源
      最近更新 更多