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

KMM项目iOS侧使用SQLDelight预填充数据库失败求助

KMM SQLDelight iOS侧数据库预填充修复方案

核心问题分析

原iOS代码的主要问题在于路径处理错误和缺失错误排查机制:

  • iOS应用的可读写目录是Documents,直接使用相对路径会触发权限问题或文件找不到的情况
  • 忽略拷贝操作的错误反馈,无法定位失败原因

修正后的实现代码

actual fun Scope.createDriver(): SqlDriver {
    val dbFileName = "dbFileName" // 和Android侧保持一致的数据库文件名

    // 1. 获取iOS应用的Documents目录路径,这是唯一可读写的安全目录
    val documentsDir = NSFileManager.defaultManager.URLForDirectory(
        directory = NSDocumentDirectory,
        inDomain = NSUserDomainMask,
        appropriateForURL = null,
        create = false,
        error = null
    )?.path ?: error("无法获取Documents目录")
    val dbPath = "$documentsDir/$dbFileName"
    val dbExists = NSFileManager.defaultManager.fileExistsAtPath(dbPath)

    if (!dbExists) {
        // 2. 获取bundle中预填充数据库的正确路径
        val bundleDbUrl = MR.assets.dbFileName.url // 确保MR.assets中的文件名与你的数据库文件完全匹配
        val bundleDbPath = bundleDbUrl.path ?: error("Bundle中未找到预填充数据库")

        // 3. 执行拷贝并处理错误
        val errorPtr = NSErrorPointer()
        val copySuccess = NSFileManager.defaultManager.copyItemAtPath(
            bundleDbPath,
            toPath = dbPath,
            error = errorPtr
        )

        if (!copySuccess) {
            errorPtr.pointee?.let {
                error("拷贝预填充数据库失败: ${it.localizedDescription}")
            } ?: error("拷贝预填充数据库失败,未知错误")
        }
    }

    // 4. 使用正确路径初始化NativeSqliteDriver
    return NativeSqliteDriver(NoteDatabase.Schema, dbPath)
}

关键注意事项

  • 资源配置:确保预填充数据库文件已添加到iOS项目资源中(通过Multiplatform Resources插件的话,放在commonMain/resources或iosMain/resources目录下)
  • 文件名一致性:Android和iOS侧的数据库文件名必须完全一致,包括后缀(如.db)
  • 错误日志:保留错误输出逻辑,能快速定位拷贝失败的具体原因,比如文件缺失、权限不足等

内容的提问来源于stack exchange,提问作者AhmadHassan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 01:02:45