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

问题描述 投票:4回答:1

必要的功能

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

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

问题

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

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

有没有我可以实现的解码方法,可以区分不存在的字段和实际设置为nil的字段?

swift encoding decoding codable
1个回答
3
投票

没有办法,但你可以添加另一个信息来了解这一点

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(代码:Optional(12),codeExists:Optional(true))

&&

这个

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

Root(代码:nil,codeExists:Optional(true))

还有这个

let str = """
{

}
"""

Root(代码:nil,codeExists:可选(false))

© www.soinside.com 2019 - 2024. All rights reserved.