2017-04-08 105 views
0

我对Swift 3和ios相当陌生,以前曾编写过访问数据库的Android程序。 目前的问题是数据库预填充了10个表,但是,当我尝试访问dbase时,无论是在模拟器还是设备中都没有表,因此无法访问数据。我搜索了论坛和互联网,但只能找到信息来检查数据库是否存在。 sqlite包装器是正在使用的FMDB。sqlite尝试访问ios时,预填充的数据库为空

代码:

override func viewDidLoad() { 
    super.viewDidLoad() 
let filemgr = FileManager.default 
let dirPaths = filemgr.urls(for: .documentDirectory, in: .userDomainMask) 

let destPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! 

databasePath = dirPaths[0].appendingPathComponent("level24.db").path 

print(databasePath) 

let fullDestPath = URL(fileURLWithPath: destPath).appendingPathComponent("level24.db") 

let bundleDatabasePath = Bundle.main.path(forResource: "level24", ofType: ".db") 

var level2DB = FMDatabase(path: databasePath as String) 


    if filemgr.fileExists(atPath: fullDestPath.path){ 
    print("Database file is exist") 
    print(filemgr.fileExists(atPath: bundleDatabasePath!)) 

    }else{ 
    filemgr.replaceItemAt(databasePath, withItemAt: bundleDatabasePath.path) 
    } 



level2DB = FMDatabase(path: databasePath as String) 
if (level2DB?.open())!{ 
      print("Database is open") 

var querySQL = "SELECT * FROM sqlite_master WHERE name = '\(tblName)' and type='table'" 
let results:FMResultSet? = level2DB?.executeQuery(querySQL, withArgumentsIn:nil) 

     if (results == nil){ 
      print("Results = \(results)") 

      do{ 
       try filemgr.copyItem(atPath: bundleDatabasePath!, toPath: fullDestPath.path) 
      }catch{ 
       print("\n",error) 
      } 

     } 
    print("Results after = \(results)") 

    let querySQL2 = "SELECT QUESTION FROM tblSani WHERE _ID = 5" 

    let results2:FMResultSet? = level2DB?.executeQuery(querySQL2, withArgumentsIn:nil) 

    print(results2?.string(forColumn: "QUESTION") as Any) 

    } 
} 

输出为:

/Users/***/Library/Developer/CoreSimulator/Devices/4F511422-2F86-49BF-AB10-5CA74B9A7B40/data/Containers/Data/Application/58DD87EB-C20F-4058-B9BC-CCD7ECEEFA98/Documents/level24.db 
Database is open 
Results after = Optional(<FMResultSet: 0x608000245220>) 
2017-04-05 21:09:26.833 Level 2[3161:210849] DB Error: 1 "no such table: tblSani" 
2017-04-05 21:09:26.833 Level 2[3161:210849] DB Query: SELECT QUESTION FROM tblSani WHERE _ID = 5 
2017-04-05 21:09:26.834 Level 2[3161:210849]DBPath: /Users/***/Library/Developer/CoreSimulator/Devices/4F511422-2F86-49BF-AB10-5CA74B9A7B40/data/Containers/Data/Application/58DD87EB-C20F-4058-B9BC-CCD7ECEEFA98/Documents/level24.db 
nil 

,如果你能帮助我找到一个解决问题的方法我们将不胜感激。

+0

你检查了'replaceItemAt'是否被调用,你尝试从模拟器或应用程序删除应用程序,然后重新安装吗? – luk2302

+0

嗨luk2302已经在模拟器和设备上都尝试过了,但没有运气,当我在数据库浏览器中打开时,仍然没有dbase中的表 – Badgersoft

回答

0

在此工作了几个小时我已经想出了这个解决方案后: 这是投入AppDelegate.swift和将检查在应用程序的启动

代码:

var filemgr = FileManager.default 
static let dirPaths = FileManager().urls(for: .documentDirectory, in: .userDomainMask) 
static let destPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! 

var databasePath = dirPaths[0].appendingPathComponent("level24.db").path 

static let fullDestPath = URL(fileURLWithPath: destPath).appendingPathComponent("level24.db") 

static let bundleDatabasePath = Bundle.main.path(forResource: "level24", ofType: ".db") 

//function to check if dbase exists 
func checkdbase(){ 

    print(databasePath) 

    print("Full path = \(AppDelegate.fullDestPath)") 

    var level2DB = FMDatabase(path: databasePath as String) 


    if filemgr.fileExists(atPath: AppDelegate.fullDestPath.path){ 

     print("Database file is exist") 
     print(filemgr.fileExists(atPath: AppDelegate.bundleDatabasePath!)) 
     print("bundle = \(AppDelegate.bundleDatabasePath)") 

     let level2DB = FMDatabase(path: databasePath as String) 

     if (level2DB?.open())!{ 
      print("Database is open") 

     // use a select statement for a known table and row 
    let querySQL2 = "SELECT * FROM tblSani WHERE _ID = 5" 

      let results:FMResultSet? = level2DB?.executeQuery(querySQL2, withArgumentsIn:nil) 

       if results?.next()==true{ 
        print("Database has tables") 

       }else{ 
        print("Database no tables") 
        removeDB() 

       } 

     } 
    }else{ 
     removeDB() 
    } 
} 

//function to remove existing dbase then unpack the dbase from the bundle 
func removeDB(){ 

    do{ 
     try filemgr.removeItem(atPath: AppDelegate.fullDestPath.path) 
     print("Database removed") 

    }catch { 
     NSLog("ERROR deleting file: \(AppDelegate.fullDestPath)") 
    } 

    do{ 
     try filemgr.copyItem(atPath: AppDelegate.bundleDatabasePath!, toPath: AppDelegate.fullDestPath.path) 
     print("Databse re-copied") 
    }catch{ 
     print("\n",error) 
    } 

} 

通话从AppDelegate中“didFinishLaunchingWithOptions”

checkdbase() 

如果能够改善这种应答功能,请做帮助别人谁可能有同样的问题