CodingKeyRepresentable - ShenYj/ShenYj.github.io GitHub Wiki

CodingKeyRepresentable

Swift 5.6 引入了一个新的 CodingKeyRepresentable 协议

该协议允许将具有非纯 StringInt 类型作为字典这种容器的 Key 值来使用

  • e.g. 使用枚举作为字典中的键,然后将其编码为 JSON 并打印出结果字符串:

    enum OldSettings: String, Codable {
        case name
        case twitter
    }
    
    let oldDict: [OldSettings: String] = [.name: "Paul", .twitter: "@twostraws"]
    let oldData = try JSONEncoder().encode(oldDict)
    let string = String(decoding: oldData, as: UTF8.self)
    print(string)

    得到的结果是: ["name","Paul","twitter","@twostraws"]

    尽管枚举具有 String 原始值,但由于字典键不是 StringInt,因此结果字符串将是 ["twitter","@twostraws","name","Paul"] – 四个单独的字符串值,而不是显然是键/值对的东西。 Swift 足够聪明,可以在解码中识别这一点,并将每对中的交替字符串与原始枚举键和字符串值进行匹配,但如果将这段 JSON 发送到服务器,服务器可不认

新的 CodingKeyRepresentable 解决了这个问题,允许正确编写新的字典键。

  • 但是,由于这改变了 Codable JSON 的编写方式,因此必须显式添加 CodingKeyRepresentable 一致性以获取新行为

    enum OldSettings: String, Codable, CodingKeyRepresentable {
        case name
        case twitter
    }
    
    let oldDict: [OldSettings: String] = [.name: "Paul", .twitter: "@twostraws"]
    let oldData = try JSONEncoder().encode(oldDict)
    
    let string = String(decoding: oldData, as: UTF8.self)
    
    print(string)

    只增加了一个协议,就解决了这个问题,得到结果: {"twitter":"@twostraws","name":"Paul"}

⚠️ **GitHub.com Fallback** ⚠️