1

假设我有一个struct User模型,其中包含许多属性。

struct User: Codable {
    let firstName: String
    let lastName: String
    // many more properties...
}

正如您在上面看到的,它符合Codable. 想象一下,如果该lastName属性应该被编码/解码为secondName并且我想将它保留lastName在我的最后,我需要将它添加CodingKeysUser模型中。

struct User: Codable {
    //...
    private enum CodingKeys: String, CodingKey {
        case firstName
        case lastName = "secondName"
        // all the other cases...
    }
}

是否有任何可能的方法来避免包含与上述示例中具有相同值的所有casesin (感觉多余)?我知道如果我避免in它在解码/编码时不会被包含在内。但是,有没有办法可以覆盖这种行为?CodingKeysrawValuefirstNamecasesCodingKeys

4

2 回答 2

2

有一种可编码的方式,但好处是值得怀疑的。

创建一个泛型CodingKey

struct AnyKey: CodingKey {
    var stringValue: String
    var intValue: Int?

    init?(stringValue: String) { self.stringValue = stringValue; self.intValue = nil }
    init?(intValue: Int) { self.stringValue = String(intValue); self.intValue = intValue }
}

并添加一个自定义keyDecodingStrategy

struct User: Codable {
    let firstName: String
    let lastName: String
    let age : Int
}

let jsonString = """
{"firstName":"John", "secondName":"Doe", "age": 30}
"""

let data = Data(jsonString.utf8)

do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .custom({ keyPath -> CodingKey in
        let key = keyPath.last!
        return key.stringValue == "secondName" ? AnyKey(stringValue:"lastName")! : key
    })
    let result = try decoder.decode(User.self, from: data)
    print(result)
} catch {
    print(error)
}
于 2020-07-03T09:49:19.523 回答
1

目前没有这样的功能。但是您可以利用计算属性并制作原始属性private

struct User: Codable {
    var firstName: String
    private var secondName: String
    var lastName: String { 
        get { secondName }
        set { secondName = newValue }
    }
}

所以根本不需要手动实现,CodingKeys它的行为就像你喜欢的那样。看看他们的同行:

预览1

于 2020-07-03T09:39:10.170 回答