在模型绑定一章中,已经介绍了模型绑定及其内建支持的类型。对于不支持的类,则无法进行字段映射。
- class MyClass {
- var variable1: String = ""
- var variable2: String = ""
- }
- class Sample: TableCodable {
- var myClass: MyClass? = nil // 编译错误,myClass 无法进行字段映射
- enum CodingKeys: String, CodingTableKey {
- typealias Root = Sample
- static let objectRelationalMapping = TableBinding(CodingKeys.self)
- case myClass
- }
- }
而本章将介绍开发者如何进行自定义字段映射类型,同时还将提供文件模版和代码模版以简化定义的操作。
ColumnCodable
自定义类需要支持字段映射并不复杂,只需实现 ColumnCodable
协议皆可。ColumnCodable
由 ColumnEncodable
和 ColumnDecodable
组成,以下是它们的原型:
- public protocol ColumnCodableBase {
- static var columnType: ColumnType {get}
- }
- public protocol ColumnEncodable: Encodable, ColumnCodableBase {
- func archivedValue() -> FundamentalValue // 将该类型转换为基础类型
- }
- public protocol ColumnDecodable: Decodable, ColumnCodableBase {
- init?(with value: FundamentalValue) // 将基础类型转换为该类型
- }
FundamentalValue
为该类在数据库中存储的形式。例如,Int
可以以 Int64
的形式存储。Date
既可以以时间戳 Double
的形式存储,也可以以 JSON 序列化后 Data
的形式存储。这需要开发者自行确定。而 archivedValue
和 init?(with:)
实际上就是序列化和反序列化的过程。
以上述的 MyClass
为例,可以以 JSON 的方式对其进行存储,并支持字段映射。JSON 的输出为 Data
,因此其可以实现为:
- // 错误示例,请勿参照
- class MyClass: ColumnCodable {
- var variable1: String
- var variable2: String
- static var columnType: ColumnType {
- return .BLOB
- }
- required init?(with value: FundamentalValue) {
- let data = value.dataValue
- guard data.count > 0 else {
- return nil
- }
- guard let dictionary = try? JSONDecoder().decode([String: String].self, from: data) else {
- return nil
- }
- variable1 = dictionary["variable1"] as? String ?? ""
- variable2 = dictionary["variable2"] as? String ?? ""
- }
- func archivedValue() -> FundamentalValue {
- guard let data = try? JSONEncoder().encode([
- "variable1": variable1,
- "variable2": variable2]) else {
- return FundamentalValue(data)
- }
- return FundamentalValue(nil)
- }
- }
由于 JSON 是比较常用的序列化和反序列化方式,因此 WCDB Swift 基于 Swift 4.0 的 Codable 协议,实现了默认的 ColumnJSONCodable
。
- class MyClass: ColumnJSONCodable {
- var a: String = ""
- var b: String = ""
- }
文件与代码模版
自定义字段映射类型中,有部分是格式固定的代码,因此,WCDB Swift 提供了文件模版和代码模版两种方式,以简化操作。
文件和代码模版都在源代码的 tools/templates
目录下,链入 WCDB Swift 时会自动安装。
文件模版
文件模版安装完成后,在 Xcode 的菜单 File
-> New
-> File…
中创建新文件,选择 ColumnCodable
。
在弹出的菜单中依次
- 输入文件名
- 选择 Language 为 Swift
- 选择对应的基础类型
代码模版
在代码文件中的任意位置,输入 ColumnCodableClass
后选择对应基础类型的代码模版即可。
文件和代码模版都是以class
作为例子的,实际上struct
甚至enum
都可以作为字段映射的类型。