WCDB之常见错误(六)
前言
在使用和测试过程中,遇到过一些报错信息,后续经过一段时间才定位到问题,特记录
问题一
更新try database.update(table:xxx, on:xxx, with:xxx)
报错datatype mismatch
[ERROR] Code:Mismatch Source:SQLite,Path:/Users/xxx/Library/Developer/CoreSimulator/Devices/xxxxxx/data/Containers/Data/Application/2D5D2272-C60C-46E7-9DEF-9AF8927F0C53/Library/xxxx/test.sqlite,SQL:UPDATE xxxTable SET aid = ?1, bId = ?2, cName,Message:datatype mismatch
问题二
执行查询语句时let list: [XXX]? = try database?.getObjects(on: xxx,fromTable: xxx, where:xxx)
时报
WCDBSwift/Select.swift:131: Assertion failed: Properties must belong to PeopleDBModel.CodingKeys.
原因时查询出来结构化好的模型类似于转换的模型不一致,检查下修改为一致即可
问题三
定义数据库对应的模型时报错
Extension outside of file declaring enum 'XXXX' prevents automatic synthesis of 'encode(to:)' for protocol 'Encodable'
Extension outside of file declaring enum 'xxxx' prevents automatic synthesis of 'init(from:)' for protocol 'Decodable'
这是由于定义的枚举类型针对ColumnCodable
的扩展与枚举定义不在同一个文件里,增加标准的模板化代码即可
1
2
3
4
5
6
7
8
9
10
11
12
extension XXXX: ColumnCodable {
// ===start===由于分类与定义不在同一个文件,需要自定decoder\encoder
init(from decoder: any Decoder) throws {
let container = try decoder.singleValueContainer()
let val = try container.decode(RawValue.self)
self.init(rawValue: val)!
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(self.rawValue)
}
}
Type 'XXXX' does not conform to protocol 'ColumnDecodable'
Type 'XXXX' does not conform to protocol 'ColumnEncodable'
这是没有实现ColumnCodable
协议,写如下代码即可
1 2 3 4 5 6 7 8 9 10 11 12 13 extension XXXX: ColumnCodable { // ** ColumnCodable -- start **/ static var columnType: ColumnType { return .integer32 } init?(with value: Value) { self.init(rawValue: value.intValue) } func archivedValue() -> Value { return Value(self.rawValue) } // ** ColumnCodable -- end **/ }完整实现的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 extension XXXX: ColumnCodable { // ===start===由于分类与定义不在同一个文件,需要自定decoder\encoder init(from decoder: any Decoder) throws { let container = try decoder.singleValueContainer() let val = try container.decode(RawValue.self) self.init(rawValue: val)! } func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() try container.encode(self.rawValue) } // ===end===由于分类与定义不在同一个文件,需要自定decoder\encoder // ** ColumnCodable -- start **/ static var columnType: ColumnType { return .integer32 } init?(with value: Value) { self.init(rawValue: value.intValue) } func archivedValue() -> Value { return Value(self.rawValue) } // ** ColumnCodable -- end **/ }
问题四
结构体或类 struct
、class
实现ColumnJSONCodable
时报错
1、
Extension outside of file declaring struct 'XXX' prevents automatic synthesis of 'encode(to:)' for protocol 'Encodable'
2、Extension outside of file declaring struct 'XXXX' prevents automatic synthesis of 'init(from:)' for protocol 'Decodable'
3、Extension outside of file declaring class 'XXXX' prevents automatic synthesis of 'encode(to:)' for protocol 'Encodable'
4、Extension outside of file declaring class 'XXXX' prevents automatic synthesis of 'init(from:)' for protocol 'Decodable''
实现如下模板代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// xxx.swift
struct XXXX {
// 是否好友
var isFriend: Bool = false
// 好友备注名
var remarkName: String = String()
init() {}
}
// xxx+exts.swift
extension XXXX: ColumnJSONCodable {
// ** 由于struct的定义,与extension不在同一个文件里才需要 -- start **/
enum CodingKeys: String, CodingKey {
case isFriend
case remarkName
}
func encode(to encoder: any Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(isFriend, forKey: .isFriend)
try container.encode(remarkName, forKey: .remarkName)
}
init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
isFriend = try container.decode(Bool.self, forKey: .isFriend)
remarkName = try container.decode(String.self, forKey: .remarkName)
}
}