排除不需要更改的 CodingKeys?

Posted

技术标签:

【中文标题】排除不需要更改的 CodingKeys?【英文标题】:Exclude CodingKeys that doesn't need to be altered? 【发布时间】:2020-07-03 09:28:44 【问题描述】:

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

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

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

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

是否有任何可能的方法来避免在CodingKeys 中包含与rawValue 具有相同值的所有cases,就像上面示例中的firstName 一样(感觉多余)?我知道如果我避免在CodingKeys 中使用cases,它将不会在解码/编码时包含在内。但是,有没有办法可以覆盖这种行为?

【问题讨论】:

让我知道如果我不够清楚或者这是重复的,我只能找到说明如何排除不必要(编码/解码时不需要)键的那个。 您从过去 2 天开始没有参与 :p 一切都好吗? 【参考方案1】:

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

创建一个通用的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)

【讨论】:

这似乎更像是为了实现所需要做的事情。但是,感觉有点过于复杂了。 确实挺麻烦的。我只是想证明这是可能的。【参考方案2】:

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

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

所以根本不需要手动实现CodingKeys,它的行为完全符合您的喜好。看看他们的同行:

【讨论】:

使用计算属性可能是最好的选择。正如你所说,它确实按要求行事。 我接受您的回答,因为它是正确的。但是,我期待更多。虽然不知道具体是什么。大声笑!

以上是关于排除不需要更改的 CodingKeys?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Swift Codable 中排除属性?

当超类也是 Codable 时,如何在子类中使用 CodingKeys?

获取 CodingKeys 键值

解码 JSON 时出错 - keyNotFound(CodingKeys

`convertFromSnakeCase` 策略不适用于 Swift 中的自定义 `CodingKeys`

Swift Parse JSON 错误:没有与键 CodingKeys 关联的值(stringValue: \"_source\