If I have a structure that conforms to the Codable protocol, for example:
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? }
How can I create an encoder and decoder that encodes / decodes it to / from an instance of type Dictionary<String, Any?> same way?
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 : I know that you can use the JSONEncoder and JSONDecoder classes before giving the result to the dictionary object, but I do not want this for efficiency reasons.
The standard Swift library comes with the JSONEncoder and JSONDecoder , as well as the PListEncoder and PListDecoder , which conform to the Encoder and Decoder protocols respectively.
My problem is that I do not know how to implement these protocols for my custom encoder and decoder classes:
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 { } }
Given that Swift is open, you can view the source code for JSONEncoder and PListEncoder in the standard library, but the source files are huge and difficult to understand due to the lack of documentation, except for a few comments.