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
相关产品推荐
相关产品推荐

