Swift 訪問 sqlite,最快的上手案例

可使用sqlite做爲關係數據庫來存儲iOS本地數據。這意味着,經過sql語言方便的作數據的增刪改查。javascript

sqlite自己提供了C語言的API,使用Swift訪問須要java

  1. 建立一個橋接文件,引入C API,訪問SQLite數據庫須要使用SQLite官方提供的C語言風格的API,因此須要添加橋接文件
  2. 引入sqlite的動態連接庫

首先咱們讓Swift到Sqlite的道路打通。mysql

訪問sqlite的C語言庫

建立一個Single View App以後,須要一些使人厭倦的操做的過程程序員

一、點擊項目名稱 - 查看General頁面 - Linked Frameworks and Libraries - 「+」 - 搜索「libsqlite3.dylib」 - 而後點擊Addsql

  1. 新建一個頭文件,命名爲SQLite-Bridge.h。具體過程爲:數據庫

    右擊項目名稱 - New File… - Header File - 命名爲「SQLite-Bridge.h」,複製代碼

並在這個頭文件中加一行代碼app

#import "sqlite3.h"複製代碼

注意,此處包含的頭文件,是sqlite3.h,而不是sqlite.h。函數

  1. 把此頭文件設置爲橋接文件。首先定位到修改點,操做過程爲:ui

    點擊項目名稱 - Build Settings - 點擊All - 點擊Combined - 單擊「Objective-C Bridging Header」(能夠經過搜索「bridging」快速定位此配置項) -  雙擊後面後彈出添加文件名,把剛剛建立的頭文件名稱寫進去- 而後回車複製代碼
  2. 編譯。若是編譯經過,那麼Swift到sqlite的連接過程就算對了。spa

一個sqlite訪問的封裝和使用案例

爲了方便讓Swift App使用,作一個封裝是必要的。封裝代碼可讓開發者只要使用此查詢執行函數、而沒必要關心sqlite的C API的底層細節,就能夠和數據庫完成交互。以下案例,不只包括封裝於類Sqlite的代碼,也包括使用此代碼的使用方法。案例中建立了一個todo的表,而且在其中插入一條數據,而後作一個查詢,打印查詢出來的結果:

import UIKit
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
        var window : UIWindow?
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            window = UIWindow()
            window!.rootViewController = UIViewController()
            window!.rootViewController!.view.backgroundColor = .blue
            window!.makeKeyAndVisible()
            let dbname = "mysqlite"
            let db = Sqlite(dbname)
            if db.createDatabase(){
                print("建立數據庫 OK")
            }
            print(db.ExecuteQuery( "CREATE TABLE IF NOT EXISTS 'todo' ('id' integer NOT NULL PRIMARY KEY AUTOINCREMENT, 'item' TEXT);"))
            print(db.ExecuteQuery( "insert into todo(item)values('1');"))
            print(db.SelectQuery( "select * from todo;"))
            return true
        }
    }
    class Sqlite: NSObject
    {
        var dbname :String!
        var DBpath :String!
        init(_ dbname:String){
            super.init()
            self.dbname = dbname
            self.DBpath = self.databasePath()
        }
        func createDatabase()->Bool
        {
            var success:Bool=false
            print(DBpath)
            if (FileManager.default.fileExists(atPath: DBpath))
            {
                success = true
            }
            else
            {
                let pathfrom:String=(Bundle.main.resourcePath! as NSString).appendingPathComponent(dbname)
                do {
                    try FileManager.default.copyItem(atPath: pathfrom, toPath: DBpath)
                    success = true
                } catch _ {
                    success = false
                }
            }
            return success
        }
        func databasePath() -> String
        {
            var path:Array=NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
            let directory=path[0]
            let DBpath=(directory as NSString).appendingPathComponent(dbname)
            return DBpath as String
        }
        func ExecuteQuery(_ str:String) -> Bool
        {
            var result:Bool=false
            var db: OpaquePointer? = nil
            var stmt:OpaquePointer? = nil
            let strExec=str.cString(using: String.Encoding.utf8)
            if (sqlite3_open(DBpath, &db)==SQLITE_OK)
            {
                if (sqlite3_prepare_v2(db, strExec! , -1, &stmt, nil) == SQLITE_OK)
                {
                    if (sqlite3_step(stmt) == SQLITE_DONE)
                    {
                        result=true
                    }
                }
                sqlite3_finalize(stmt)
            }
            sqlite3_close(db)
            return result
        }
        func SelectQuery(_ str:String) -> Array<Dictionary<String,String>>
        {
            var result:Array<Dictionary<String,String>>=[]
            var db: OpaquePointer? = nil
            var stmt:OpaquePointer? = nil
            let strExec=str.cString(using: String.Encoding.utf8)
            if ( sqlite3_open(DBpath,&db) == SQLITE_OK)
            {
                if (sqlite3_prepare_v2(db, strExec! , -1, &stmt, nil) == SQLITE_OK)
                {
                    while (sqlite3_step(stmt) == SQLITE_ROW)
                    {
                        var i:Int32=0
                        let icount:Int32=sqlite3_column_count(stmt)
                        var dict=Dictionary<String, String>()
                        while i < icount
                        {
                            let strF=sqlite3_column_name(stmt, i)
                            let strV = sqlite3_column_text(stmt, i)
                            let rFiled:String=String(cString: strF!)
                            let rValue:String=String(cString: strV!)
                            dict[rFiled] = rValue
                            i += 1
                        }
                        result.insert(dict, at: result.count)
                    }
                    sqlite3_finalize(stmt)
                }
                sqlite3_close(db)
            }
            return result
        }
    }複製代碼

做爲程序員,能夠直接使用此類作數據庫的訪問,若是對sqlite內部C API的使用感興趣,則能夠進一步的閱讀此類的實現部分。

相關文章
相關標籤/搜索