You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)
    }
}

额外注意点

  1. 原代码中n.append(color[dbname])会报错,因为dbname是Expression<String?>,取出的值为可选类型,需要解包(示例中用?? ""提供默认空字符串)。
  2. 确保导入UIKit框架,否则UIColor无法正常使用。

内容的提问来源于stack exchange,提问作者J A S K I E R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 15:24:51