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

7
如果我有一个符合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?
}

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

注意:我知道在将结果转换为字典对象之前可以使用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 {

    }
}

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 {

    }
}

鉴于Swift是开源的,可以查看标准库中JSONEncoderPListEncoder类的源代码,但源文件很大且缺乏文档,除了一些注释外,很难理解。

如果您不想使用JSONDecoder,那么为什么要实现Codable协议呢? - NSAdi
1
Codable协议是通用的/泛型的,可以用来表示具有本地Swift类型的外部数据结构。Swift标准库有EncoderDecoder协议,您可以实现它们来为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 - Toni Sučić
1
我的问题是代码太过复杂,除了代码库中的注释外,没有文档说明如何实现符合EncoderDecoder协议的自定义编码器和解码器。 - Toni Sučić
1个回答

1
如果您查看JSONDecoder的实现(这里),您会发现它是一个两步骤的过程:1.使用JSONSerializationData转换为json字典,然后2.创建一个内部类_JSONDecoder的实例来执行字典->Codable对象转换。
在Swift论坛上有一些关于暴露内部类型的讨论,Swift团队可能会在未来做出一些改变。也有人提供了一个第三方框架来实现您想要的功能。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接