gpt4 book ai didi

ios - 使用 Swift 的 Encodable 将可选属性编码为 null 而无需自定义编码

转载 作者:IT王子 更新时间:2023-10-29 05:38:20 25 4
gpt4 key购买 nike

我想使用符合 Encodable 协议(protocol)的 struct 使用 Swift 的 JSONEncoder 对可选字段进行编码。

默认设置是 JSONEncoder 使用 encodeIfPresent 方法,这意味着 nil 的值被排除在 Json 之外。

如何在不编写我的自定义 encode(to encoder: Encoder) 函数的情况下为单个属性覆盖它,在该函数中我必须为所有属性实现编码(如 this article 建议在下面“自定义编码”)?

例子:

struct MyStruct: Encodable {
let id: Int
let date: Date?
}

let myStruct = MyStruct(id: 10, date: nil)
let jsonData = try JSONEncoder().encode(myStruct)
print(String(data: jsonData, encoding: .utf8)!) // {"id":10}

最佳答案

import Foundation

enum EncodableOptional<Wrapped>: ExpressibleByNilLiteral {
case none
case some(Wrapped)
init(nilLiteral: ()) {
self = .none
}
}

extension EncodableOptional: Encodable where Wrapped: Encodable {

func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .none:
try container.encodeNil()
case .some(let wrapped):
try wrapped.encode(to: encoder)
}
}
}

extension EncodableOptional{

var value: Optional<Wrapped> {

get {
switch self {
case .none:
return .none
case .some(let v):
return .some(v)
}
}

set {
switch newValue {
case .none:
self = .none
case .some(let v):
self = .some(v)
}
}
}
}

struct User: Encodable {
var name: String
var surname: String
var age: Int?
var gender: EncodableOptional<String>
}

func main() {
var user = User(name: "William", surname: "Lowson", age: 36, gender: nil)
user.gender.value = "male"
user.gender.value = nil
print(user.gender.value ?? "")
let jsonEncoder = JSONEncoder()
let data = try! jsonEncoder.encode(user)
let json = try! JSONSerialization.jsonObject(with: data, options: [])
print(json)

let dict: [String: Any?] = [
"gender": nil
]
let d = try! JSONSerialization.data(withJSONObject: dict, options: [.prettyPrinted])
let j = try! JSONSerialization.jsonObject(with: d, options: [])
print(j)
}

main()

这将在执行 main 后为您提供输出:

{
age = 36;
gender = "<null>";
name = William;
surname = Lowson;
}
{
gender = "<null>";
}

因此,您可以看到我们对性别进行了编码,因为它在字典中为空。您将获得的唯一限制是您必须通过 value 属性访问可选值

关于ios - 使用 Swift 的 Encodable 将可选属性编码为 null 而无需自定义编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47290582/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com