首页 > 解决方案 > 使用 Codable 将字符串编码/解码为整数,并在两者之间使用函数

问题描述

我有这个 json 字符串:

let json = """
    {
        "name": "Wendy Carlos",
        "hexA": "7AE147AF",
        "hexB": "851EB851"
    }
"""
let data = Data(json.utf8)

...我想使用 Codable 对这个结构进行编码(和返回):

struct CodeMe: Codable {
  var name: String
  var hexA: Int
  var hexB: Int
    
  enum CodingKeys: String, CodingKey {
    case name, hexA, hexB
  }
}
let encoder = JSONEncoder()
let decoder = JSONDecoder()

但是 hexA 和 hexB 是字符串(在 JSON 中),我需要这些是 Swift 对象中的 Ints。为此,我已经编写了 20 个函数。例如在伪代码中:

func hexAConversion(from hex: String)->Int {
    // returns an Int between -50 and 50
}

func hexBConversion(from hex: String)->Int {
    // returns an Int between 0 and 360
}

考虑到这样的转换方案相当多,并且我需要编写 20 个以上的函数(用于 Int->Hexadecimal 往返),我将如何编写与上述方法一起使用的自定义解码和编码策略?

我看过这些解决方案:Swift 4 JSON Decodable 最简单的解码类型更改的方法,但我的用例似乎略有不同,因为接受的答案看起来像是处理直接类型转换,而我需要运行一些函数。

标签: swiftcodable

解决方案


对于Codable需要自定义转换类型的编码和解码,您只需要自己实现初始化程序和编码方法。在你的情况下,它看起来像这样。试图真正清楚地传达这个想法有点冗长。

init(from decoder: Decoder) throws {
    let container = try decoder.container(keyedBy: CodingKeys.self)
    self.name = try container.decode(String.self, forKey: .name)
    let hexAString: String = try container.decode(String.self, forKey: .hexA)
    self.hexA = hexAConversion(from: hexAString)
    let hexBString: String = try container.decode(String.self, forKey: .hexB)
    self.hexB = hexBConversion(from: hexBString)
}

func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    //Assuming you have another set of methods for converting back to a String for encoding
    try container.encode(self.name, forKey: .name)
    try container.encode(hexAStringConversion(from: self.hexA), forKey: .hexA)
    try container.encode(hexBStringConversion(from: self.hexB), forKey: .hexB)
}

推荐阅读