Swift - 在解码可选的 Codable 值时,有没有办法区分字段不存在或字段 nil/null

Swift - Is there a way to differentiate between a field not being present or a field being nil/null when decoding an optional Codable value

必要的功能

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

由于某些补丁请求需要能够将实际的 NULL 值发送到 API(如果它是 nil 可选,则不仅仅是忽略该字段),这意味着我需要能够编码和解码nil/NULL 某些字段的默认值。

问题

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

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

问题

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

没有办法,但您可以添加其他信息以了解

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

This method returns nil if the container does not have a value associated with key, or if the value is null. The difference between these states can be distinguished with a contains(_:) call.

所以解码

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