使用Swift为iOS应用接入外部Sqlite数据库相关问题咨询
现有代码问题说明
你当前的代码确实会新建空白的同名数据库。你指向的是Documents目录下的文件路径,如果你没有预先把自己准备的Photos.sqlite放到对应路径下,sqlite3_open接口检测到路径无对应文件时,会自动创建一个空白的同名数据库,不会关联你提前准备好的文件。
适配方案
方案1:纯只读场景(最适配你的需求)
你不需要做写入操作的话,完全不用把文件放到Documents目录,直接读取app主包内的预置数据库即可,步骤如下:
- 把你提前准备好的
Photos.sqlite拖入Xcode项目中,勾选「Copy items if needed」,同时在「Add to targets」列表中勾选你的app目标,确保文件会被打包到app安装包内。 - 打开数据库时直接读取主包内的文件路径即可,推荐用只读模式打开,避免意外创建空库,示例代码如下:
func openPrebuiltDB() -> OpaquePointer? { // 获取主包内Photos.sqlite的路径 guard let filePath = Bundle.main.path(forResource: "Photos", ofType: "sqlite") else { print("未找到预置的数据库文件,请检查是否已正确加入项目") return nil } var db: OpaquePointer? // 以只读模式打开,路径不存在时也不会自动创建空库 guard sqlite3_open_v2(filePath, &db, SQLITE_OPEN_READONLY, nil) == SQLITE_OK else { print("打开数据库失败: \(String(cString: sqlite3_errmsg(db)))") sqlite3_close(db) return nil } return db }
方案2:需要后续写入数据的场景
如果你后续需要修改数据库内容,才需要把预置库复制到Documents等可读写目录下,步骤如下:
- 同方案1第一步,先把
Photos.sqlite加入Xcode项目 - 首次启动app时判断Documents目录下是否存在该文件,不存在就从主包复制过去,再打开Documents下的文件即可,示例代码:
func copyAndOpenDB() -> OpaquePointer? { let docURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("Photos.sqlite") // 检查Documents下是否已经有数据库,没有就从主包复制 if !FileManager.default.fileExists(atPath: docURL.path) { guard let bundleDBPath = Bundle.main.path(forResource: "Photos", ofType: "sqlite") else { print("主包内未找到预置数据库") return nil } do { try FileManager.default.copyItem(atPath: bundleDBPath, toPath: docURL.path) } catch { print("复制数据库失败: \(error)") return nil } } // 打开Documents下的可读写数据库 var db: OpaquePointer? guard sqlite3_open(docURL.path, &db) == SQLITE_OK else { print("打开数据库失败: \(String(cString: sqlite3_errmsg(db)))") sqlite3_close(db) return nil } return db }
内容的提问来源于stack exchange,提问作者Justin Philip Fulkerson
相关产品推荐
相关产品推荐

