ylo*_*orn 2 dictionary swift4 encodable jsonencoder
我只是很好奇如何将具有String键和Encodable值的字典编码为JSON。
例如:
let dict: [String: Encodable] = [
"Int": 1,
"Double": 3.14,
"Bool": false,
"String": "test"
]
Run Code Online (Sandbox Code Playgroud)
其中的键dict都是type String,但是值的类型各不相同。
但是,JSON中允许所有这些类型。
我想知道JSONEncoder在Swift 4中是否有一种方法可以将其编码dict为JSON Data。
我确实知道还有其他方法无法使用JSONEncoder,但是我只是想知道是否JSONEncoder有能力进行管理。
将Dictionary确实有func encode(to encoder: Encoder) throws在扩展,但仅适用于约束Key: Encodable, Key: Hashable, Value: Encodable,而对于我们dict,它需要约束Key: Encodable, Key: Hashable, Value == Encodable。
struct为此拥有一个就足够了JSONEncoder,
struct Test: Encodable {
let int = 1
let double = 3.14
let bool = false
let string = "test"
}
Run Code Online (Sandbox Code Playgroud)
但是,我很想知道是否可以在不指定具体类型而仅指定Encodable协议的情况下完成此操作。
只是想出了一种使用包装器实现此目的的方法:
struct EncodableWrapper: Encodable {
let wrapped: Encodable
func encode(to encoder: Encoder) throws {
try self.wrapped.encode(to: encoder)
}
}
let dict: [String: Encodable] = [
"Int": 1,
"Double": 3.14,
"Bool": false,
"String": "test"
]
let wrappedDict = dict.mapValues(EncodableWrapper.init(wrapped:))
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .prettyPrinted
let jsonData = try! jsonEncoder.encode(wrappedDict)
let json = String(decoding: jsonData, as: UTF8.self)
print(json)
Run Code Online (Sandbox Code Playgroud)
结果如下:
{“ Double”:3.1400000000000001,“ String”:“ test”,“ Bool”:false,“ Int”:1}
我仍然不满意。如果还有其他方法,我很高兴看到它。
谢谢!
JSONEncoder:extension JSONEncoder {
private struct EncodableWrapper: Encodable {
let wrapped: Encodable
func encode(to encoder: Encoder) throws {
try self.wrapped.encode(to: encoder)
}
}
func encode<Key: Encodable>(_ dictionary: [Key: Encodable]) throws -> Data {
let wrappedDict = dictionary.mapValues(EncodableWrapper.init(wrapped:))
return try self.encode(wrappedDict)
}
}
let dict: [String: Encodable] = [
"Int": 1,
"Double": 3.14,
"Bool": false,
"String": "test"
]
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .prettyPrinted
let jsonData = try! jsonEncoder.encode(dict)
let json = String(decoding: jsonData, as: UTF8.self)
print(json)
Run Code Online (Sandbox Code Playgroud)
结果:
{“ Int”:1,“ Double”:3.1400000000000001,“ Bool”:false,“ String”:“ test”}
private extension Encodable {
func encode(to container: inout SingleValueEncodingContainer) throws {
try container.encode(self)
}
}
extension JSONEncoder {
private struct EncodableWrapper: Encodable {
let wrapped: Encodable
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try self.wrapped.encode(to: &container)
}
}
func encode<Key: Encodable>(_ dictionary: [Key: Encodable]) throws -> Data {
let wrappedDict = dictionary.mapValues(EncodableWrapper.init(wrapped:))
return try self.encode(wrappedDict)
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1382 次 |
| 最近记录: |