可使用sqlite做爲關係數據庫來存儲iOS本地數據。這意味着,經過sql語言方便的作數據的增刪改查。javascript
sqlite自己提供了C語言的API,使用Swift訪問須要java
首先咱們讓Swift到Sqlite的道路打通。mysql
建立一個Single View App以後,須要一些使人厭倦的操做的過程程序員
一、點擊項目名稱 - 查看General頁面 - Linked Frameworks and Libraries - 「+」 - 搜索「libsqlite3.dylib」 - 而後點擊Addsql
新建一個頭文件,命名爲SQLite-Bridge.h。具體過程爲:數據庫
右擊項目名稱 - New File… - Header File - 命名爲「SQLite-Bridge.h」,複製代碼
並在這個頭文件中加一行代碼app
#import "sqlite3.h"複製代碼
注意,此處包含的頭文件,是sqlite3.h,而不是sqlite.h。函數
把此頭文件設置爲橋接文件。首先定位到修改點,操做過程爲:ui
點擊項目名稱 - Build Settings - 點擊All - 點擊Combined - 單擊「Objective-C Bridging Header」(能夠經過搜索「bridging」快速定位此配置項) - 雙擊後面後彈出添加文件名,把剛剛建立的頭文件名稱寫進去- 而後回車複製代碼
編譯。若是編譯經過,那麼Swift到sqlite的連接過程就算對了。spa
爲了方便讓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的使用感興趣,則能夠進一步的閱讀此類的實現部分。