如何在swift中捆绑预先填充的数据库

Man*_*olo 6 sqlite database-connection swift

我知道有很多相关的帖子,但我注意到他们都没有解释这样做的方式,大多数人说要查看文档,我看起来已经看了但似乎缺乏有关将预先填充的数据库带到Swift的信息

我有一个旧的数据库.db,超过60k行三列,我想用FMDB包装器带到我的swift SQLite应用程序,该应用程序在iPhone中工作,我试图将contacts.db拖到应用程序但我无法访问它.在设备中运行时,应用程序始终启动新数据库.

我将数据库复制到支持文件文件夹,并尝试在app文件夹中,无法访问

有没有人这样做并愿意告诉我该怎么做?

总之,我正在寻找的是将我的contacts.db插入应用程序(包),以便我可以访问设备而不是在模拟器中.我不需要在设备中添加删除或编辑contact.db,数据库加载了所需的所有信息,用户只能进行搜索并能够显示结果.

class ViewController: UIViewController {

@IBOutlet weak var name: UITextField!
@IBOutlet weak var address: UITextField!

var databasePath = NSString()    

override func viewDidLoad() {
    super.viewDidLoad()

    if let resourceUrl = NSBundle.mainBundle().URLForResource("contacts", withExtension: "db") {
        if NSFileManager.defaultManager().fileExistsAtPath(resourceUrl.path!) 
    }
    let filemgr = NSFileManager.defaultManager()
    let dirPaths =
    NSSearchPathForDirectoriesInDomains(.DocumentDirectory,
            .UserDomainMask, true)

    let docsDir = dirPaths[0] as! String

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

    if !filemgr.fileExistsAtPath(databasePath as String) {

        let contactDB = FMDatabase(path: databasePath as String)

        if contactDB == nil {
            println("Error: \(contactDB.lastErrorMessage())")
        }

        if contactDB.open() {
            let sql_stmt = "CREATE TABLE IF NOT EXISTS CONTACTS (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, ADDRESS TEXT, PHONE TEXT)"
            if !contactDB.executeStatements(sql_stmt) {
                println("Error: \(contactDB.lastErrorMessage())")
            }
            contactDB.close()
        } else {
            println("Error: \(contactDB.lastErrorMessage())")
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

rvg*_*rvg 6

Swift 2示例

一些假设:

  1. 您已libsqlite3.tbd正确添加到项目中.
  2. 您已正确地将sqlite数据库添加到项目中.
  3. 您已将所需的FMDB文件正确复制到项目中.
  4. 你有一个ViewController调用 ViewController.swift

在Xcode中打开您的ViewController.swift文件,找到以下代码:

 override func viewDidLoad() {
     super.viewDidLoad()
     // Do any additional setup after loading the view, typically from a nib.
Run Code Online (Sandbox Code Playgroud)

在注释下面添加以下代码,请记住在第4行和第5行中更改数据库的名称.

     // Start of Database copy from Bundle to App Document Directory
     let fileManager = NSFileManager.defaultManager()
     let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
     let destinationSqliteURL = documentsPath.URLByAppendingPathComponent("sqlite.db")
     let sourceSqliteURL = NSBundle.mainBundle().URLForResource("sqlite", withExtension: "db")

     if !fileManager.fileExistsAtPath(destinationSqliteURL.path!) {
         // var error:NSError? = nil
         do {
             try fileManager.copyItemAtURL(sourceSqliteURL!, toURL: destinationSqliteURL)
             print("Copied")
             print(destinationSqliteURL.path)
         } catch let error as NSError {
             print("Unable to create database \(error.debugDescription)")
         }
     }


     // Let's print the path to the database on your Mac
     // so you can go look for the database in the Finder.
     print(documentsPath)

     let db = FMDatabase(path: destinationSqliteURL.path)

    // Let's open the database
    if !db.open() {
        print("Unable to open database")
        return
    }

    // Let's run some SQL from the FMDB documents to make sure
    // everything is working as expected.  
    if !db.executeUpdate("create table test(x text, y text, z text)", withArgumentsInArray: nil) {
        print("create table failed: \(db.lastErrorMessage())")
    }

    if !db.executeUpdate("insert into test (x, y, z) values (?, ?, ?)", withArgumentsInArray: ["a", "b", "c"]) {
        print("insert 1 table failed: \(db.lastErrorMessage())")
    }

    if !db.executeUpdate("insert into test (x, y, z) values (?, ?, ?)", withArgumentsInArray: ["e", "f", "g"]) {
        print("insert 2 table failed: \(db.lastErrorMessage())")
    }

    if let rs = db.executeQuery("select x, y, z from test", withArgumentsInArray: nil) {
        while rs.next() {
            let x = rs.stringForColumn("x")
            let y = rs.stringForColumn("y")
            let z = rs.stringForColumn("z")
            print("x = \(x); y = \(y); z = \(z)")
        }
    } else {
        print("select failed: \(db.lastErrorMessage())")
    }

    db.close()
Run Code Online (Sandbox Code Playgroud)

您应该能够立即运行项目并复制数据库.

以前的答案,如果它有助于某人

FMDB文档对此主题非常有帮助.使用那里的示例,下面的代码应该假设以下事项:

  1. 您正在使用Swift 1.2或以后.
  2. 您已正确添加FMDB到项目中.
  3. 调用的SQLite数据库contacts.db已正确添加到项目中.
  4. Build Phases,然后Link Binary With Libraries你已经添加libsqlite3.dylib.

    //
    //  ViewController.swift
    //
    
    import UIKit
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var name: UITextField!
        @IBOutlet weak var address: UITextField!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            let filemgr = NSFileManager.defaultManager()
            let documentsFolder = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! String
            let path = documentsFolder.stringByAppendingPathComponent("contacts.db")
            let database = FMDatabase(path: path)
    
            if !database.open() {
                println("Unable to open database")
                return
            }
    
            if !database.executeUpdate("create table test(x text, y text, z text)", withArgumentsInArray: nil) {
                println("create table failed: \(database.lastErrorMessage())")
            }
    
            if !database.executeUpdate("insert into test (x, y, z) values (?, ?, ?)", withArgumentsInArray: ["a", "b", "c"]) {
                println("insert 1 table failed: \(database.lastErrorMessage())")
            }
    
            if !database.executeUpdate("insert into test (x, y, z) values (?, ?, ?)", withArgumentsInArray: ["e", "f", "g"]) {
                println("insert 2 table failed: \(database.lastErrorMessage())")
            }
    
            if let rs = database.executeQuery("select x, y, z from test", withArgumentsInArray: nil) {
                while rs.next() {
                    let x = rs.stringForColumn("x")
                    let y = rs.stringForColumn("y")
                    let z = rs.stringForColumn("z")
                    println("x = \(x); y = \(y); z = \(z)")
                }
            } else {
                println("select failed: \(database.lastErrorMessage())")
            }
    
            database.close()
    
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)

要测试,只需使用Build and Run按钮,您应该看到在Xcode的控制台中运行模拟器和以下结果:

x = a; y = b; z = c
x = e; y = f; z = g 
Run Code Online (Sandbox Code Playgroud)

要显示控制台,请键入Shift + CMD + R或转到视图 - >调试区域 - >激活控制台


Mar*_*rra 2

首先,如果您使用 FMDB,这与核心数据无关。

其次,它实际上相当简单。

在 Xcode 中,您将 SQL 文件作为资源包含在内,在构建应用程序时将其加载到应用程序中。

然后您使用 找到该文件[[NSBundle mainBundle] URLForResource:@"file" withExtension:@"sqlite"]。从那里您可以像往常一样继续使用 FMDB。

如果您想写入该文件,则需要将其复制到应用程序沙箱中的可写位置。

更新1

您正在捆绑包中找到该文件,但在尝试打开它之前并未将其从捆绑包中复制到文档目录中。如果文档目录中当前不存在该文件,则需要将其从捆绑包中复制出来。