Swift数据解析(第四篇) - SmartCodable(上)

2,336 阅读2分钟

这是Swift数据解析方案的系列文章:

Swift数据解析(第一篇) - 技术选型

Swift数据解析(第二篇) - Codable 上

Swift数据解析(第二篇) - Codable 下

Swift数据解析(第三篇) - Codable源码学习

Swift数据解析(第四篇) - SmartCodable 上

Swift数据解析(第四篇) - SmartCodable 下

优秀的数据解析库是什么样的?

  • 使用安全:不要出现crash,
  • 容错情况:遇到异常的数据可以兼容掉,兼容全场景。
  • 执行效率:执行效率高。
  • 使用方便:框架接口使用简单,代码量越少越好。
  • 学习成本:学习成本低,上手容易。

经过前面几篇的学习,我们对Codable有了深入的理解。我们来评判一下Codable符合哪条,不符合哪条。

Codable的缺点

缺点1: 兼容性差

使用Codable 协议 进行 decode 时候,遇到以下三种情况就会失败。并且只有一个属性解析失败时就抛出异常,导致整个解析失败:

  • 类型键不存在
  • 类型键不匹配
  • 数据值是null

期望遇到异常的数据,Codable可以尝试兼容,尽可能的避免排除解析异常,避免整段解析失败,完成解析。

类型键不存在

填充对应类型的默认值,让解析继续进行下去。 我们需要开发一个功能,通过获取键的类型,返回对应的默认值。 例如:Bool类型的默认值返回False,Int类型的默认值返回, 可选类型的默认值返回nil。

类型键不匹配

类型键不匹配的兼容较为复杂。如果我们的模型中定义的属性类型是Bool,但是数据返回的是Int类型的0或1,或String类型的“false”,“true”等。虽然类型不匹配,但是数据仍然是有价值的。所以第一步我们需要做的是: 尝试对不匹配的类型数据进行转换。如果转换失败,再提供对应类型的默认值。

数据值是null

使用对应的默认值进行填充。

缺点2: 使用不便

struct Feed: Codable {
    var name: String
    var id: Int
}

let dict = [
    "id": 2,
    "name": "小明",
] as [String : Any]

let jsonStr = dict.bt_toJSONString() ?? ""
guard let jsonData = jsonStr.data(using: .utf8) else { return }
let decoder = JSONDecoder()
do {
    let feed = try decoder.decode(Feed.self, from: jsonData)
    print(feed)
} catch let error {
    print(error)
}
  • 数据类型转换太多,先将字典转成Json字符串,再将Json字符串转Data。

  • 需要调用do-catch,代码实现上不便。

SmartCodable

SmartCodable 就是针对Codable的缺点,进行了一次封装。保留了Codable优势的同时,也解决了Codable的缺点。