fl0*_*034 10 encoding json ios swift codable
我想JSONEncoder
使用struct
符合Encodable
协议的Swift编码可选字段.
默认设置是JSONEncoder
使用encodeIfPresent
方法,这意味着nil
从Json中排除的值.
如何在不编写自定义encode(to encoder: Encoder)
函数的情况下为单个属性覆盖此属性,我必须在其中实现所有属性的编码(如本文在"自定义编码"下建议的那样)?
例:
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}
Run Code Online (Sandbox Code Playgroud)
让我为此建议一个属性包装器。
import Foundation
@propertyWrapper
public struct CodableExplicitNull<Wrapped> {
public var wrappedValue: Wrapped?
public init(wrappedValue: Wrapped?) {
self.wrappedValue = wrappedValue
}
}
extension CodableExplicitNull: Encodable where Wrapped: Encodable {
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch wrappedValue {
case .some(let value): try container.encode(value)
case .none: try container.encodeNil()
}
}
}
extension CodableExplicitNull: Decodable where Wrapped: Decodable {
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if !container.decodeNil() {
wrappedValue = try container.decode(Wrapped.self)
}
}
}
extension CodableExplicitNull: Equatable where Wrapped: Equatable { }
extension KeyedDecodingContainer {
public func decode<Wrapped>(_ type: CodableExplicitNull<Wrapped>.Type,
forKey key: KeyedDecodingContainer<K>.Key) throws -> CodableExplicitNull<Wrapped> where Wrapped: Decodable {
return try decodeIfPresent(CodableExplicitNull<Wrapped>.self, forKey: key) ?? CodableExplicitNull<Wrapped>(wrappedValue: nil)
}
}
Run Code Online (Sandbox Code Playgroud)
struct Test: Codable {
@CodableExplicitNull var name: String? = nil
}
let data = try JSONEncoder().encode(Test())
print(String(data: data, encoding: .utf8) ?? "")
let obj = try JSONDecoder().decode(Test.self, from: data)
print(obj)
Run Code Online (Sandbox Code Playgroud)
给予
{"name":null}
Test(name: nil)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2960 次 |
最近记录: |