定义词典编码器和解码器为在夫特的可编码的协议4
问题描述:
如果我有一个符合Codable
协议像这样一个结构:定义词典编码器和解码器为在夫特的可编码的协议4
enum AnimalType: String, Codable {
case dog
case cat
case bird
case hamster
}
struct Pet: Codable {
var name: String
var animalType: AnimalType
var age: Int
var ownerName: String
var pastOwnerName: String?
}
如何创建的编码器&编码解码器/解码它来自/类似于Dictionary<String, Any?>
类似实例的实例?
let petDictionary: [String : Any?] = [
"name": "Fido",
"animalType": "dog",
"age": 5,
"ownerName": "Bob",
"pastOwnerName": nil
]
let decoder = DictionaryDecoder()
let pet = try! decoder.decode(Pet.self, for: petDictionary)
NB:我知道,这是可能的结果铸造Dictionary对象前使用JSONEncoder
和JSONDecoder
类,但我不希望出于效率的考虑。
雨燕标准库自带JSONEncoder
和JSONDecoder
还有PListEncoder
和PListDecoder
类右出分别符合Encoder
和Decoder
协议的盒子。
我的问题是,我不知道如何实现这些协议为我定制的编码器和解码器类:
class DictionaryEncoder: Encoder {
var codingPath: [CodingKey]
var userInfo: [CodingUserInfoKey : Any]
func container<Key>(keyedBy type: Key.Type) -> KeyedEncodingContainer<Key> where Key : CodingKey {
}
func unkeyedContainer() -> UnkeyedEncodingContainer {
}
func singleValueContainer() -> SingleValueEncodingContainer {
}
}
class DictionaryDecoder: Decoder {
var codingPath: [CodingKey]
var userInfo: [CodingUserInfoKey : Any]
func container<Key>(keyedBy type: Key.Type) throws -> KeyedDecodingContainer<Key> where Key : CodingKey {
}
func unkeyedContainer() throws -> UnkeyedDecodingContainer {
}
func singleValueContainer() throws -> SingleValueDecodingContainer {
}
}
由于雨燕是开源的,它可以查看源代码标准库中的JSONEncoder和PListEncoder类,但源文件非常庞大且难以理解,因为除了一些评论外,缺少文档。
答
如果你看看JSONDecoder
(here)的实现,你会看到,这是一个过程分为两个步骤:1.使用JSONSerialization
到Data
转换成JSON字典,然后2.创建一个内部的一个实例类_JSONDecoder
做字典 - >Codable
对象转换。
有some discussion on the Swift forums可能暴露内部类型,Swift团队可能会在未来做些什么。有人还提供了第三方框架来做你想做的事情。
如果你不想使用JSONDecoder,那么为什么要实现Codable协议? – NSAdi
Codable协议是泛化的/通用的,可用于使用本机Swift类型来表示外部数据结构。 Swift标准库具有'Encoder'和'Decoder'协议,您可以使用它们来为Codable协议创建您自己的自定义编码器和解码器。 Swift标准库附带两个这样的编码器/解码器对: https://github.com/apple/swift/blob/master/stdlib/public/SDK/Foundation/PlistEncoder.swift https:// github。 com/apple/swift/blob/master/stdlib/public/SDK/Foundation/JSONEncoder.swift –
我的问题在于代码太复杂了,除了代码库中的注释以外,没有任何文档解释您可以如何分别实施符合“编码器”和“解码器”协议的自定义编码器和解码器。 –