2015-09-17 12 views
6

Sto cercando di includere un database SQLite precompilato (con wrapper FMDB) in una build sul mio iPhone fisico. Tuttavia, il database precompilato non viene incluso nella build sul dispositivo fisico.Swift - Database SQLite precompilato non incluso nel dispositivo

Nota che funziona correttamente in IOS Simulator, ma solo per un dispositivo simulatore.

Ho incluso il database in Fasi di compilazione> Copia risorse in bundle e link libsqlite3.dylib in Link binario con librerie.

Quale codice Swift devo aggiungere per ottenere il database incluso nella build sul dispositivo fisico?

Codice:

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. 
    } 
} 

AGGIORNAMENTO - lavoro Swift 2 codice in Xcode 7 - Pre-popolato database SQLite usando FMDB involucro copiati sul dispositivo OK fisico:

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

Perché la mia domanda ha votato in basso ???? – IlludiumPu36

+0

l'elettore non ha lasciato commenti, quindi ho votato in rialzo per contro votare. –

risposta

2

da quello che ho vedere che non dovrebbe funzionare su alcun simulatore/dispositivo poiché si accede al file nella cartella dei documenti. non è nel tuo pacchetto.

ciò che devi fare è copiare il file dal pacchetto nella directory di documenti prima di tentare di aprire lì:

//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 ... grazie per l'upvote! XCode voleva una modifica al seguente per includere il bit di errore: filemgr.copyItemAtPath (bundleDatabasePath, toPath: databasePath, error: nil), ma ora sto ricevendo "NSString non è implicitamente convertibile in 'String', intendevi 'as' convertire esplicitamente? " – IlludiumPu36

+0

si passa da swift 1.2 a 2 - il codice sopra riportato è 1.2 ma l'errore è 2.0 - databasePath non dovrebbe mai essere una NSString :) –

+0

Forse XCode è il problema ... Sto usando la v6.4. – IlludiumPu36

2

Ho avuto un problema simile; in particolare, dopo aver aggiunto i dati a un'app su cui sto lavorando nel simulatore iPhone, non ho voluto aggiungere di nuovo tutti quei dati al mio dispositivo fisico iPhone. Dopo aver guardato le soluzioni offerte da IlludimPu36 e Daij-Djan, mi si avvicinò con il seguente metodo, che io chiamo nella prima linea dal metodo di App Delegato (AppDelegate.swift) applicazione (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 _ { 
     } 
    } 
} 

Sembra funzionare e passare da una riga all'altra del metodo nel debugger appare senza errori per ogni caso, sia quando il database non è già lì (cioè dopo una nuova installazione dopo aver eliminato l'app o aver ripristinato il simulatore), e quando il database esiste già. Ottengo gli stessi risultati anche su un dispositivo fisico.

Grazie a IlludiumPu36 e @ Daij-Djan per fornire suggerimenti/risposte a questo, e spero che questo possa aiutare qualcun altro.

Problemi correlati