2017-10-19 169 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團隊可能會在未來做些什麼。有人還提供了第三方框架來做你想做的事情。