使 Swift Class 具有字符或基于字符的 属性 可编码

Making Swift Class With Character Or Character-Based Property Codable

Swift 4 中的字符 class 似乎没有实现 Codable 协议。我想了解这样做的理由,因为 class 似乎有资格作为 Swift.

中的基础 class

看看下面的(故意剥离的)递归 class,在保留使用 Character 作为 Dictionary 键的同时使其可编码的最佳方法是什么?

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

谢谢!

您可以使 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.isEmpty else {
            throw DecodingError.dataCorruptedError(in: container, debugDescription: "Decoder expected a Character but found an empty string.")
        }
        guard string.count == 1 else {
            throw DecodingError.dataCorruptedError(in: container, debugDescription: "Decoder expected a Character but found a string: \(string)")
        }
        self = string[string.startIndex]
    }
    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)
}