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

标签 sqlite swift database-connection

我知道有很多相关的帖子,但我注意到它们都没有解释如何做到这一点,大多数人说要查看文档,我已经看过但似乎缺乏关于将预填充数据库引入的信息 swift

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

我把数据库复制到supporting files文件夹下,在app文件夹里也试了下,都进不去

有没有人已经这样做了并且愿意告诉我如何去做?

总而言之,我正在寻找的是将我的 contacts.db 插入到应用程序( bundle )中,这样我就可以在设备中而不是在模拟器中进行访问。我不需要添加删除或编辑设备中的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())")
        }
    }

}

最佳答案

Swift 2 示例

一些假设:

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

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

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

在注释下方添加以下代码,请记得在第 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()

您现在应该能够运行该项目并复制您的数据库。

以前的答案,以防对某人有帮助

documentation for FMDB对这个话题很有帮助。使用那里的例子,下面的代码应该在假设以下情况下工作:

  1. 您正在使用 Swift 1.2 或更高版本。
  2. 您已将 FMDB 正确添加到您的项目中。
  3. 名为 contacts.db 的 SQLite 数据库已正确添加到项目中。
  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.
        }
    }
    

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

x = a; y = b; z = c
x = e; y = f; z = g 

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

关于sqlite - 如何在 swift 中捆绑预填充的数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29908398/

相关文章:

java - 我在 SqLite 中得到了错误的日期

bash - 通过 bash 执行 sqlite 命令

swift - 如何在 Swift 2 中将 UInt8 转换为 Bool

swift - xcode9.2 中的链接器命令失败,退出代码为 1(使用 -v 查看调用)

.net - 在 odbc 连接中使用 like 语句

Android cursor.getColumnNames() 不包含新添加的列

返回 ID 和位置的 SQLite SELECT

swift - 对库变量使用 Swift 组合框架

mysql - 无法连接 : Lost connection to MySQL server at 'reading initial communication packet' , 系统错误:0

php - 如何通过 Internet 将数据更新远程发送到托管的 MySQL 数据库?