iOS 16.0+适配SQLite Pod时出现类型转换错误求助
解决SQLite类型不匹配错误:String转Int64/Expression转Expression<Int64?>
升级项目最低适配版本到iOS 16.0+并集成SQLite Pod后,出现以下两类类型不匹配错误:
Cannot convert value of type 'String' to expected argument type 'Int64'
或
Cannot convert value of type 'Expression' to expected argument type 'Expression<Int64?>'
核心问题出在数据库列表达式的初始化方式错误,导致表达式类型与数据库实际列类型不匹配。
错误原因分析
你的代码中创建Expression时错误使用了value:参数:
let id = Expression<Int64>(value: "id") let dbname = Expression<String?>(value: "name") // 其他列同理
Expression<T>(value: ...)是SQLite.swift中用于创建字面量表达式的初始化方法(比如查询时传入固定值),而定义数据库列对应的表达式,应该直接传入列名字符串,不需要value:参数。错误的写法会把列名字符串当成字面量值,导致表达式类型和数据库实际列类型冲突,iOS 16+下类型检查更严格,因此触发报错。
修复方案
将所有列表达式的初始化改为直接传入列名,移除value:参数:
import Foundation import SQLite import UIKit // 引入UIKit以使用UIColor class Sql { var i = [Int64]() var c = [UIColor]() var n = [String]() var d = [String]() func read() -> ([Int64], [UIColor], [String], [String]){ // 将所有代码包裹在do...catch中以处理错误 do { let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) let dbFile = "\(path.first ?? "")/db.sqlite3" let db = try Connection(dbFile) let history = Table("history") // 修复:直接传入列名,移除value:参数 let id = Expression<Int64>("id") let dbname = Expression<String?>("name") let dbr = Expression<Int>("r") let dbg = Expression<Int>("g") let dbb = Expression<Int>("b") let dbdate = Expression<Date>("date") let df = DateFormatter() df.dateFormat = "yyyy-MM-dd HH:mm:ss" let exist = try db.scalar(history.exists) if !exist { do { print("数据库不存在 - 创建数据库") try db.run(history.create { t in t.column(id, primaryKey: true) t.column(dbname) t.column(dbr) t.column(dbg) t.column(dbb) t.column(dbdate) }) } catch { print("捕获错误 - 创建存储数据库失败") print(error) } print("数据库创建成功") } else { print("数据库已存在") } i.removeAll() c.removeAll() n.removeAll() d.removeAll() // 遍历查询结果 for color in try db.prepare(history.order(dbdate.desc)) { i.append(color[id]) c.append(UIColor( red: CGFloat(Double(color[dbr]) / 255.0), green: CGFloat(Double(color[dbg]) / 255.0), blue: CGFloat(Double(color[dbb]) / 255.0), alpha: 1.0 )) // 修复:处理可选类型的name字段,提供默认空字符串 n.append(color[dbname] ?? "") let readDate = df.string(from: color[dbdate]) d.append(readDate) } } catch { print("捕获错误,读取前终止 :(") print(error) } return (i, c, n, d) } }
额外注意点
- 原代码中
n.append(color[dbname])会报错,因为dbname是Expression<String?>,取出的值为可选类型,需要解包(示例中用?? ""提供默认空字符串)。 - 确保导入
UIKit框架,否则UIColor无法正常使用。
内容的提问来源于stack exchange,提问作者J A S K I E R
相关产品推荐
相关产品推荐

