首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift Encodable:将nil编码为空对象

Swift Encodable:将nil编码为空对象
EN

Stack Overflow用户
提问于 2021-09-27 13:15:04
回答 3查看 267关注 0票数 2

如何将nil属性编码为空JSON对象?

代码语言:javascript
复制
struct Foo: Encodable {
    let id = 10
    let bar: Bar? = nil
}

struct Bar: Encodable {
    let number: Int
}

let data = try! JSONEncoder().encode(Foo())

print(String(data: data, encoding: .utf8)!)

这将打印出来:

"{"id":7}"

我想要的是:

"{"id":7, "bar":{}}"

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-09-28 05:18:33

我不确定为什么需要这样做,因为对解码失败的表单进行编码通常是不会做的。

尽管如此,如果您发现自己在多个地方需要这种逻辑,您可以使用这种功能扩展KeyedEncodingContainer

代码语言:javascript
复制
extension KeyedEncodingContainer {
    mutating func encodeOptional<T: Encodable>(_ value: T?, forKey key: Self.Key) throws {
        if let value = value { try encode(value, forKey: key) }
        else { try encode([String:String](), forKey: key) }
    }
}

,然后在Foo中实现encode(to:)方法

代码语言:javascript
复制
struct Foo: Encodable {
    let id = 10
    let bar: Bar? = nil
    
    enum CodingKeys: String, CodingKey {
        case id
        case bar
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(id, forKey: .id)
        try container.encodeOptional(bar, forKey: .bar)
    }
}

如果您发现自己需要在其他类型的容器中为nil值编码空UnkeyedDecodingContainer对象,还可以使用类似的encodeOptional方法扩展JSON和SingleValueDecodingContainer

票数 1
EN

Stack Overflow用户

发布于 2021-09-27 14:02:01

当为bar = nil时,可以向encoder引入没有属性的空结构

代码语言:javascript
复制
struct Foo: Encodable {
    let id = 10
    let bar: Bar? = nil
    
    enum CodingKeys : String, CodingKey {
        case id
        case bar
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(id, forKey: .id)
        
        if let bar = bar {
            try container.encode(bar, forKey: .bar)
        }
        else {
            try container.encode(Empty(), forKey: .bar)
        }
    }
}

struct Bar: Encodable {
    let number: Int
}

struct Empty: Encodable {
}
票数 3
EN

Stack Overflow用户

发布于 2021-09-27 15:16:19

Foo实现自定义encode(to:),如果Bar为空,则使用空字典

代码语言:javascript
复制
struct Foo: Encodable {
    let id = 10
    let bar: Bar? = nil

    enum CodingKeys: String, CodingKey {
        case id, bar
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(id, forKey: .id)
        switch bar {
        case .some(let value):
            try container.encode(value, forKey: .bar)
        case .none:
            try container.encode([String: Bar?](), forKey: .bar)
        }
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69347300

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档