2015-09-17 116 views
6

我試圖在我的物理iPhone中包含預填充的SQLite數據庫(使用FMDB包裝器)。但是,預填充數據庫不包含在構建物理設備中。Swift - 未包含在設備上的預填充SQLite數據庫

請注意,它在IOS模擬器中工作正常,但只適用於一個模擬器設備。

我已經將數據庫包含在Build Binses> Copy Bundled Resources和鏈接庫libsqlite3.dylib下。

我需要添加什麼Swift代碼才能將構建中的數據庫包含到物理設備中?

代碼:

import UIKit 

class ViewController: UIViewController { 


    @IBOutlet weak var checkButton: UIButton! 
    @IBOutlet weak var tests_scroller: UITextView! 

    var databasePath = NSString() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     checkButton.setTitle("\u{2610}", forState: .Normal) 
     checkButton.setTitle("\u{2611}", forState: .Selected) 


     let filemgr = NSFileManager.defaultManager() 

     let dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) 

     let docsDir = dirPaths[0] as! String 

     databasePath = docsDir.stringByAppendingPathComponent("vmd_db.db") 

     let myDatabase = FMDatabase(path: databasePath as String) 


     if myDatabase.open(){ 

      var arrayData:[String] = [] 

      let query_lab_test = "SELECT lab_test FROM lab_test ORDER BY lab_test ASC" 

      let results_lab_test:FMResultSet? = myDatabase.executeQuery(query_lab_test, withArgumentsInArray: nil) 

      while results_lab_test?.next() == true { 

       if let resultString = results_lab_test?.stringForColumn("lab_test"){ 

       arrayData.append(resultString) 

      } 
     } 
      var multiLineString = join("\n", arrayData) 
      tests_scroller.text = multiLineString 
      myDatabase.close() 
    } 
    } 




    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 
} 

更新 - XCode中7工作斯威夫特2碼 - 使用FMDB包裝複製到物理設備確定預填充SQLite數據庫:從什麼

import UIKit 

class ViewController: UIViewController { 

    @IBOutlet weak var tests_scroller: UITextView! 

    var databasePath = NSString() 

    override func viewDidLoad() { 
     super.viewDidLoad() 


     let sourcePath = NSBundle.mainBundle().pathForResource("vmd_db", ofType: "db") 

     let documentDirectoryPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as String! 

     let destinationPath = (documentDirectoryPath as NSString).stringByAppendingPathComponent("vmd_db.db") 

     do {         
      try NSFileManager().copyItemAtPath(sourcePath!, toPath: destinationPath) 

     } catch _ {     
     } 

     //read it 
     let myDatabase = FMDatabase(path: destinationPath as String) 

     if myDatabase.open(){ 

      var arrayData:[String] = [] 

      let query_lab_test = "SELECT lab_test FROM lab_test ORDER BY lab_test ASC" 

      let results_lab_test:FMResultSet? = myDatabase.executeQuery(query_lab_test, withArgumentsInArray: nil) 

      while results_lab_test?.next() == true { 

       if let resultString = results_lab_test?.stringForColumn("lab_test"){ 

        arrayData.append(resultString) 

       } 
      } 

      let multiLineString = arrayData.joinWithSeparator("\n") 

      tests_scroller.text = multiLineString 
      myDatabase.close() 
     } 
    } 


    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 
} 
+0

爲什麼我的問題被拒絕? – IlludiumPu36

+0

下來選民留下沒有評論,所以我upvoted反投票。 –

回答

2

我看到它不應該在任何模擬器/設備上工作,因爲您訪問文檔文件夾中的文件。這不在你的捆綁中。

你需要做的是努力沒有打開它之前從包到文檔目錄中的文件複製:

//path in documents 
let dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) 
let docsDir = dirPaths[0] 
databasePath = docsDir.stringByAppendingPathComponent("vmd_db.db") 

//if not there, copy from bundle 
if !filemgr.fileExistsAtPath(databasePath) { 
    let bundleDatabasePath = NSBundle.mainBundle().pathForResource("vm_db", ofType: "db") 
    filemgr.copyItemAtPath(bundleDatabasePath, toPath: databasePath) 
} 

//read it 
let myDatabase = FMDatabase(path: databasePath as String) 
+0

@ Daij-Djan ...感謝您的支持! XCode想要改變以下內容來包含錯誤位:filemgr.copyItemAtPath(bundleDatabasePath,toPath:databasePath,error:nil)但現在我得到了「NSString不能隱式轉換爲'String';你的意思是'as'明確轉換?「 – IlludiumPu36

+0

您在swift 1.2和2之間切換 - 上面的代碼是1.2,但錯誤是2.0 - databasePath不應該是NSString :) –

+0

也許XCode是問題...我使用的是v6.4。 – IlludiumPu36

2

我也有類似的問題;具體來說,在將數據添加到我在iPhone模擬器上工作的應用程序中之後,我不想將所有數據再次添加到我的物理iPhone設備。看着由IlludimPu36和Daij-Djan提供的解決方案後,我想出了下面的方法,這是我從應用程序委託的(AppDelegate.swift)應用程序(didFinishLaunchingWithOptions)方法的第一行稱:

func copyBundledSQLiteDB() { 
    let sourcePath = NSBundle.mainBundle().pathForResource("filename", ofType: "sqlite") 

    let documentDirectoryPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first as String! 

    let destinationPath = (documentDirectoryPath as NSString).stringByAppendingPathComponent("filename.sqlite") 

    // If file does not exist in the Documents directory already, 
    // then copy it from the bundle. 
    if !NSFileManager().fileExistsAtPath(destinationPath) { 
     do { 
      try NSFileManager().copyItemAtPath(sourcePath!, toPath: destinationPath) 

     } catch _ { 
     } 
    } 
} 

它似乎可以正常工作,並且在數據庫尚未存在的時候(即在刪除應用程序或重新設置模擬器之後進行全新安裝之後),在調試器中逐行瀏覽每種情況下的錯誤都是無差錯的,並且當數據庫已經存在時。我在物理設備上也得到了相同的結果。

感謝@ IlludiumPu36和@ Daij-Djan爲此提供技巧/解答,我希望這可以幫助別人。

相關問題