Table 使用 Xcode 将预加载的 sqlite 数据库添加到 iOS 应用后未找到

Table not found after adding preloaded sqlite db to iOS App using Xcode

我有一个预加载的 SQLite 数据库,名为 "myDB.dms"。我想打包数据库并从应用程序中访问内容。

首先,我将数据库文件拖放到 Xcode ProjectNavigator window 中,然后在提示符下单击 "Copy files if needed"。

我使用 FMDB 库访问 SQLite 数据库。

我创建了一个新的数据库接口 class 并添加了 3 种不同的方法:

  1. openDB
  2. copyDB
  3. 执行查询

因为将 DB 文件打包到 Bundle 资源文件夹中,我不得不将文件从资源文件夹复制到目录文件夹,如下所示:

func copyDB() -> Bool {
    let fileManager = FileManager.default
    let documentsUrl = fileManager.urls(for: .documentDirectory, in: .userDomainMask)
    var returnStatus: Bool = false

    guard documentsUrl.count != 0 else {
        print("Could not find documents url")
        return false
    }

    let finalDatabaseURL = documentsUrl.first!.appendingPathComponent(dbFileName)

    if !((try? finalDatabaseURL.checkResourceIsReachable()) ?? false) {
        print("DB does not exist in documents folder")

        let documentsURL = Bundle.main.resourceURL?.appendingPathComponent(dbFileName)

        do {
            try fileManager.copyItem(atPath: (documentsURL?.path)!, toPath: finalDatabaseURL.path)
        } catch let error as NSError {
            print ("Couldnt copy file to final location! Error:\(error.description)")
            returnStatus = false
        }
    } else {
        print ("Database file found at path: \(finalDatabaseURL.path)")
        returnStatus = true
    }

    return returnStatus
}

下面是 OpenDatabase 的代码

func openDB() -> Bool {
    let fileManager = FileManager.default
    let documentsUrl = fileManager.urls(for: .documentDirectory, in: .userDomainMask)
    let dbPath = documentsUrl.first!.appendingPathComponent(dbFileName)
    let database = FMDatabase(url: dbPath)

    var returnStatus: Bool = false

    if (self.copyDB() == false) {
        returnStatus = false
    } else {
        if (!database.open(withFlags: 1)) {
            print("Could not open database at \(dbPath.absoluteString)")
            returnStatus = false
        } else {
            self.database = database
            returnStatus = true
        }
    }

    return returnStatus
}

以下是执行查询的代码

func executeQuery(queryString:String) {
    print(queryString)
    do {
        if (database.open()){
            let results:FMResultSet = try database.executeQuery(queryString, values: nil)

            if results.next() == true {
                print(results)
            }
        }
    } catch let error as NSError {
        print(error.description)
    }
}

copyDB() 和 openDB() 工作正常,但随后我尝试执行 Query(),出现以下错误:

Error Domain=FMDatabase Code=1 "no such table: tableName" UserInfo={NSLocalizedDescription=no such table: tableName}

下面是有效的代码:

    func copyDataBase() -> Bool {
    let fileManager = FileManager.default
    var dbPath = ""

    do {
        dbPath = try fileManager.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent(dbFileName).path
    } catch {
        print(error.localizedDescription)
        return false
    }

    if !fileManager.fileExists(atPath: dbPath) {
        let dbResourcePath = Bundle.main.path(forResource: "dbName", ofType: "sqlite")
        do {
            try fileManager.copyItem(atPath: dbResourcePath!, toPath: dbPath)
        } catch {
            print(error.localizedDescription)
            return false
        }
    }
    return true
}

希望对有需要的人有所帮助

  Firstly Create FileManager Object. Get Path and check file is exist or not then copy items from db.
     func callForCopyDBAllObejct() -> Bool {
     let fileM = FileManager.default
     var dbPath = nil

    do {
      dbPath = try fileM.url(for: .applicationSupportDirectory, 
 in: .userDomainMask, appropriateFor: nil, create: 
   true).appendingPathComponent(dbFileName).path
   } catch {
      print(error.localizedDescription)
       return false
   }

     if !fileM.fileExists(atPath: dbPath) {
       let dbResourcePath = Bundle.main.path(forResource: "dbName", 
   ofType: "sqlite")
       do {
         try fileM.copyItem(atPath: dbResourcePath!, toPath: 
    dbPath)
       } catch {
        print(error.localizedDescription)
        return false
       }
   }
   return true

}