用于Swift 4中Codable协议的自定义字典编码器和解码器

Ton*_*čić 7 dictionary encoder decoder swift codable

如果我有一个符合Codable协议的结构,如下所示:

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?
}
Run Code Online (Sandbox Code Playgroud)

如何创建一个编码器和解码器,将其编码/解码为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)
Run Code Online (Sandbox Code Playgroud)

注意:我知道在将结果转换为字典对象之前可以使用JSONEncoder和JSONDecoder类,但出于效率原因我不希望这样做.

Swift标准库带有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 {

    }
}
Run Code Online (Sandbox Code Playgroud)
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 {

    }
}
Run Code Online (Sandbox Code Playgroud)

由于雨燕是开源的,它可能查看的源代码JSONEncoder和PListEncoder标准库类,但源文件是巨大的,很难理解,由于缺乏文件除了提出一些看法.

g-m*_*ark 1

JSONDecoder如果你看一下(这里)的实现,你会发现它是一个两步过程:1.使用JSONSerialization将其转换Data为json字典,然后2.创建一个内部类的实例_JSONDecoder来执行字典 ->Codable对象转换。

Swift 论坛上有一些关于可能公开内部类型的讨论,Swift 团队将来可能会对此采取一些措施。有人还提供了一个第三方框架来完成你想做的事情。