在 Swift 中编码空嵌套结构时如何省略空花括号?

How to omit empty curly brackets, when encoding empty nested structs in Swift?

我正在尝试创建一个嵌套的 Codable 结构作为我将发送到 RESTful API 的 PATCH 请求对象的一部分。我正在为所有属性使用可选值,并且正在初始化每个嵌套结构。编码时,JSON 对象中的可选项被正确省略,但初始化的空嵌套结构由“{}”表示。示例:

struct RequestData: Codable {
    var id : String?
    var created : String?
    var name : String?
    var params = Parameters()
    
    struct Parameters: Codable{
        var token: String?
        var mode: Int?
        var uid: String?
    }
}

如果我创建一个新的 RequestData 并更改 token,我得到:

var test = RequestData()
test.params.token = "1234567890"
enc = try? JSONEncoder().encode(test)

结果:{"params":{"token":"1234567890"}}

如果我这样做但不更改嵌套结构的 属性,我会得到一组大括号:

var test = RequestData()
test.name = "John, Deere"
enc = try? JSONEncoder().encode(test)

结果:{"name":"John, Deere","params":{}}

有没有办法强制 JSON 编码器在最后的 JSON 中省略空的大括号?

默认情况下它将是 {} 因为 params always 有一个值。

但是当你想添加或不添加 params 时,你可以将编码器的自定义实现写入 select:

struct RequestData: Codable {
    var id : String?
    var created : String?
    var name : String?
    var params = Parameters()
    
    struct Parameters: Codable{
        var token: String?
        var mode: Int?
        var uid: String?
        
        func isDefined() -> Bool {
            return token != nil || mode != nil || uid != nil
        }
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encodeIfPresent(id, forKey: .id)
        try container.encodeIfPresent(created, forKey: .created)
        try container.encodeIfPresent(name, forKey: .name)
        if params.isDefined() {
            try container.encode(params, forKey: .params)
        }
    }
}

func encode(to encoder: Encoder)Encodable 协议的一部分,通过使用我们自己的实现,您可以修改默认行为。

你得到空括号的原因是你在 RequestData 创建实例时初始化了 param's 值,

var params = Parameters()

而是将 params 声明为 Optional

var params: Parameters?

现在,您可以像这样创建实例,

var test = RequestData()
test.name = "John, Deere"
var params = Parameters()
params.token = "1234567890"
test.params = params