用基于字符或字符的属性Codable制作Swift类

时间:2018-03-01 02:13:11

标签: swift character protocols codable

Swift 4中的Character类似乎没有实现Codable协议。我想理解这个的基本原理,因为看起来这个课程有资格成为Swift的基础课程。

查看下面的(故意剥离的)递归类,那么在保留使用Character作为Dictionary键的同时使其成为Codable的最佳方法是什么?

class MyClass: Codable { <- does not compile
    var myProperty: [Character: MyClass]?
    var myOtherProperty: Int = 42
}

谢谢!

1 个答案:

答案 0 :(得分:1)

您可以使Character符合Codable协议,如下所示:

extension Character: Codable {
    public init(from decoder: Decoder) throws {
        var container = try decoder.unkeyedContainer()
        let string = try container.decode(String.self)
        guard string.count == 1 else {
            throw DecodingError.dataCorruptedError(in: container, debugDescription: "Multiple characters found when decoding a Character")
        }
        guard let character = string.first else {
            throw DecodingError.dataCorruptedError(in: container, debugDescription: "Empty String found when decoding a Character")
        }
        self = character
    }
    public func encode(to encoder: Encoder) throws {
        var container = encoder.unkeyedContainer()
        try container.encode(String(self))
    }
}

游乐场测试

let aClass = AClass()
let bClass = AClass()
bClass.myOtherProperty = 10
aClass.myProperty = [:]
aClass.myProperty?["B"] = bClass
aClass.myOtherProperty = 20
do {
    let jsonData = try JSONEncoder().encode(aClass)
    print(String(data: jsonData, encoding: .utf8)!)  // "{"myProperty":[["B"],{"myOtherProperty":10}],"myOtherProperty":20}\n"
    let decodedObject = try JSONDecoder().decode(AClass.self, from: jsonData)
    print(decodedObject.myProperty)      // "Optional(["B": __lldb_expr_73.AClass])\n"
    print(decodedObject.myOtherProperty) // 20
} catch {
    print(error)
}