学计算机的那个

不是我觉到、悟到,你给不了我,给了也拿不住;只有我觉到、悟到,才有可能做到,能做到的才是我的.

0%

Codable协议

Codable 本身就是个类型别名

1
typealias Codable = Decodable & Encodable

代表一个同时符合 DecodableEncodable 协议的类型,即可解码且可编码的类型。

Codable 的用法

Codable 是用来做系统自身数据结构和外部公共数据结构做转换的。系统内部数据结构可以是基础类型、结构体、枚举、类等,外部公共数据结构可以是 JSON、XML 等。

JSON 和 模型的相互转换

  1. 在 Swift 中可以通过继承 NSObject 的方式,来使用基于 OC Runtime 的 JSON 模型互转方案
  2. 苹果提供了 JSONEncoderJSONDecoder 这两个结构体来方便得在 JSON 数据和自定义模型之间互相转换.苹果可以利用一些系统私有的机制来实现转换,而不需要通过 OC Runtime
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct User: Codable {
var name: String
var age: Int
}

//解码
let json = """
{
"name": "zhangsan",
"age": 25
}
""".data(using: .utf8)!
let user = JSONDecoder().decode(User.self, from: json)

//编码
let data = JSONEncoder().encode(user)

自定义 CodingKeys

自定义 CodingKeys 主要是两个目的

  1. 当数据类型属性名和 JSON 中字段名不同时,做 key 的映射。
  2. 通过在不添加某些字段的 case,来跳过某些字段的编解码过程。
1
2
3
4
5
6
7
8
9
10
struct User: Codable {
var name: String
var age: Int
var birthday: Date?

enum CodingKeys: String, CodingKey {
case name = "userName"
case age = "userAge"
}
}

CodingKeys 必须是一个 RawValueString 类型的枚举,并符合 CodingKey 协议。以上代码实现的效果为,为 nameage 字段做了 key 映射,让编解码过程中不包含 birthday 字段。

原理浅析

在 Swift 的 JSON 转模型方法中一共有三种实现方案:

  1. Objective-C Runtime
  2. Key 映射 比如 ObjectMapper 就是这种,这种的缺点是每个对象都要写一大堆映射代码,比较麻烦
  3. 利用对象底层内存布局 SwiftyJSON 就属于这种,这种方法使用起来一样很方便,但是依赖苹果的私有代码,苹果如果调整了内部实现就会失效。

Codable 基本上就是 Key 映射的方案,只不过编译器帮我们自动合成了很多代码来让我们使用起来一样可以非常简单。由于编译器不会帮第三方库合成代码,因此 Codable 秒杀了一众基于 key 映射实现的第三方库

参考

详解 Codable 的用法和原理
Swift 之 Codable 实战技巧