2015-09-17 19 views
6

Próbuję dołączyć wstępnie wypełnioną bazę danych SQLite (z opakowaniem FMDB) w kompilacji do mojego fizycznego iPhone'a. Jednak wstępnie wypełniona baza danych nie jest uwzględniana w kompilacji na urządzeniu fizycznym.Swift - Wstępnie wypełniona baza danych SQLite nieuwzględniona na urządzeniu

Zauważ, że działa poprawnie w Symulatorach IOS, ale tylko w przypadku jednego urządzenia symulatora.

Zawarłem bazę danych w fazie budowy> Skopiuj zasoby powiązane i link libsqlite3.dylib pod Link Binary z bibliotekami.

Jaki kod Swift muszę dodać, aby baza danych dołączona do kompilacji na urządzeniu fizycznym?

Kod:

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

AKTUALIZACJA - Swift roboczy kod 2 w Xcode 7 - Pre-zaludnionych bazy danych SQLite używając FMDB opakowanie skopiowane do urządzenia fizycznego OK:

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

Dlaczego moje pytanie zostało odrzucone ???? – IlludiumPu36

+0

W dół głosujący nie pozostawił komentarza, więc przegłosowałem, aby przeciwdziałać głosowaniu. –

Odpowiedz

2

od co ja zobacz, że nie powinien działać na żadnym symulatorze/urządzeniu, ponieważ masz dostęp do pliku w folderze dokumentów. którego nie ma w twoim pakiecie.

co trzeba zrobić, to skopiować plik z pakietu do katalogu dokumentów przed próbując go otworzyć tam:

//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 ... dzięki za przegraną! XCode chciał zmienić następujące elementy, aby uwzględnić błąd: filemgr.copyItemAtPath (bundleDatabasePath, toPath: databasePath, error: nil), ale teraz otrzymuję komunikat "NSString nie jest niejawnie możliwy do zamiany na" String ", czy miałeś na myśli" jako " wyraźnie przekonwertować? " – IlludiumPu36

+0

możesz przełączać się między Swift 1.2 a 2 - powyższy kod to 1.2, ale błąd to 2.0 - databasePath nigdy nie powinien być NSString :) –

+0

Może XCode jest problemem ... Używam wersji 6.4. – IlludiumPu36

2

miałem podobny problem; konkretnie, po dodaniu danych do aplikacji, nad którą pracuję w symulatorze iPhone'a, nie chciałem dodawać wszystkich tych danych ponownie do mojego fizycznego urządzenia iPhone. Po zapoznaniu się z rozwiązań oferowanych przez IlludimPu36 i Daij-Djan, wymyśliłem następującą metodę, którą nazywamy w pierwszej linii od (AppDelegate.swift) aplikacji (didFinishLaunchingWithOptions) metody App Delegatury:

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 _ { 
     } 
    } 
} 

Wygląda na to, że działa i przechodzenie przez każdą linię metody w debugerze wygląda bezbłędnie dla każdego przypadku, zarówno gdy baza danych już nie istnieje (tj. Po świeżej instalacji po usunięciu aplikacji lub zresetowaniu symulatora), i kiedy baza danych już istnieje. Te same wyniki uzyskuję również na urządzeniu fizycznym.

Dzięki @ IlludiumPu36 i @ Daij-Djan za udzielanie wskazówek/odpowiedzi na ten temat i mam nadzieję, że pomoże to komuś innemu.

Powiązane problemy