【问题标题】:Exclude CodingKeys that doesn't need to be altered?排除不需要更改的 CodingKeys?
【发布时间】:2023-04-10 07:18:02
【问题描述】:

假设我有一个 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 一切都好吗?

标签: swift codable jsondecoder jsonencoder


【解决方案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,它的行为完全符合您的喜好。看看他们的同行:

【讨论】:

  • 使用计算属性可能是最好的选择。正如你所说,它确实按要求行事。
  • 我接受您的回答,因为它是正确的。但是,我期待更多。虽然不知道具体是什么。大声笑!
猜你喜欢
  • 1970-01-01
  • 2020-02-29
  • 2011-10-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-07
  • 2018-05-12
  • 1970-01-01
相关资源
最近更新 更多