2015-09-17 19 views
6

Tôi đang cố gắng bao gồm một cơ sở dữ liệu SQLite được điền sẵn (với trình bao bọc FMDB) trong một bản dựng cho iPhone vật lý của tôi. Tuy nhiên, cơ sở dữ liệu được điền sẵn không được bao gồm trong bản dựng cho thiết bị vật lý.Swift - Cơ sở dữ liệu SQLite được điền sẵn không có trên thiết bị

Lưu ý rằng nó hoạt động tốt trong IOS Simulator, nhưng chỉ cho một thiết bị mô phỏng.

Tôi đã bao gồm cơ sở dữ liệu trong giai đoạn xây dựng> Sao chép tài nguyên đi kèm và liên kết libsqlite3.dylib dưới liên kết nhị phân với thư viện.

Tôi cần thêm mã Swift nào để có được cơ sở dữ liệu được bao gồm trong bản dựng cho thiết bị thực?

Code:

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

CẬP NHẬT - Working Swift 2 mã trong XCode 7 - Pre-dân cư cơ sở dữ liệu SQLite sử dụng FMDB wrapper sao chép vào thiết bị OK vật lý:

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

Tại sao câu hỏi của tôi bị bỏ phiếu ???? – IlludiumPu36

+0

xuống cử tri để lại không có bình luận vì vậy tôi upvoted để bỏ phiếu. –

Trả lời

2

từ những gì tôi xem nó sẽ không hoạt động trên bất kỳ trình mô phỏng/thiết bị nào kể từ khi bạn truy cập tệp trong thư mục tài liệu. không có trong gói của bạn.

những gì bạn cần làm là sao chép các tập tin từ gói vào thư mục tài liệu trước khi cố gắng để mở nó ở đó:

//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 ... cảm ơn vì đã upvote! XCode muốn thay đổi như sau để bao gồm bit lỗi: filemgr.copyItemAtPath (bundleDatabasePath, toPath: databasePath, error: nil) nhưng bây giờ tôi nhận được "NSString không chuyển đổi hoàn toàn thành 'String'; ý của bạn là 'as' để chuyển đổi một cách rõ ràng? " – IlludiumPu36

+0

bạn chuyển đổi giữa nhanh 1,2 và 2 - mã trên của bạn là 1,2 nhưng lỗi là 2.0 - databasePath không bao giờ là NSString :) –

+0

Có thể XCode là vấn đề ... Tôi đang sử dụng v6.4. – IlludiumPu36

2

Tôi đã có một vấn đề tương tự; cụ thể, sau khi thêm dữ liệu vào ứng dụng tôi đang làm việc trên trình mô phỏng iPhone, tôi không muốn phải thêm tất cả dữ liệu đó vào thiết bị iPhone thực của mình. Sau khi xem xét các giải pháp được cung cấp bởi IlludimPu36 và Daij-Đan, tôi đã đưa ra các phương pháp sau đây, mà tôi gọi trong dòng đầu tiên từ ứng dụng phương pháp App Đại biểu của (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 _ { 
     } 
    } 
} 

Dường như nó hoạt động, và bước qua từng dòng của phương thức trong trình gỡ rối sẽ không có lỗi cho mỗi trường hợp, cả khi cơ sở dữ liệu chưa có (tức là sau khi cài đặt mới sau khi xóa ứng dụng hoặc đặt lại trình mô phỏng), và khi cơ sở dữ liệu đã tồn tại. Tôi cũng nhận được kết quả tương tự trên thiết bị vật lý.

Cảm ơn @ IlludiumPu36 và @ Daij-Djan vì đã cung cấp mẹo/câu trả lời cho điều này và tôi hy vọng điều này có thể giúp người khác ra ngoài.

Các vấn đề liên quan