2017-10-19 172 views
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对象前使用JSONEncoderJSONDecoder类,但我不希望出于效率的考虑。

雨燕标准库自带JSONEncoderJSONDecoder还有PListEncoderPListDecoder类右出分别符合EncoderDecoder协议的盒子。

我的问题是,我不知道如何实现这些协议为我定制的编码器和解码器类:

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 { 

    } 
} 

由于雨燕是开源的,它可以查看源代码标准库中的JSONEncoderPListEncoder类,但源文件非常庞大且难以理解,因为除了一些评论外,缺少文档。

+0

如果你不想使用JSONDecoder,那么为什么要实现Codable协议? – NSAdi

+1

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 –

+1

我的问题在于代码太复杂了,除了代码库中的注释以外,没有任何文档解释您可以如何分别实施符合“编码器”和“解码器”协议的自定义编码器和解码器。 –

回答

1

如果你看看JSONDecoderhere)的实现,你会看到,这是一个过程分为两个步骤:1.使用JSONSerializationData转换成JSON字典,然后2.创建一个内部的一个实例类_JSONDecoder做字典 - >Codable对象转换。

some discussion on the Swift forums可能暴露内部类型,Swift团队可能会在未来做些什么。有人还提供了第三方框架来做你想做的事情。