You can use SQLite as a relational database to store iOS local data. This means that it is easy to add, delete, change and check data through SQL language.

Sqlite itself provides a C API, which is required for Swift access

  1. Create a bridge file and introduce the C API. To access the SQLite database, you need to use the C-style API provided by SQLite, so you need to add the bridge file
  2. Introduce sqLite’s dynamic link library

First let’s get the path from Swift to Sqlite open.

Access sqLite’s C library

Once you’ve created a Single View App, you need to go through some tedious operations

1, click on the project name – view the General page – Linked Frameworks and Libraries – “+” – search for “libsqlite3.dylib” – then click Add

  1. Create a new header file and name it sqlite-bridge.h. The specific process is:

    Right click project name - New File... - Header File - Name it "sqlite-bridge. h",Copy the code

Add a line of code to the header file

    #import "sqlite3.h"Copy the code

Note that the header file included here is sqlite3.h, not sqlite.h.

  1. Set this header file as a bridge file. First locate the modification point, and the operation process is as follows:

    Click on the project name - Build Settings - Click on All - click on Combined - click on "Objective-c Bridging Header" (you can locate this configuration item quickly by searching for "Bridging") - double-click on the back to pop up the add file name, Enter the name of the header file you just created - and press EnterCopy the code
  2. Compilation. If the compilation succeeds, then the Swift to SQLite link is done correctly.

An ENCAPSULATION and use case for SQLite access

In order to facilitate the use of Swift App, it is necessary to make a package. Wrapping code allows developers to interact with the database simply by using this query execution function, without worrying about the low-level details of SQLite’s C API. The following example covers not only the code encapsulated in class Sqlite, but also how to use it. Create a toDO table, insert a column of data into it, make a query, and print the result of the query:

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(" createDatabase 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 } }Copy the code

As a programmer, you can use this class directly for database access, and if you are interested in using SQLite’s internal C API, you can read the implementation section of this class further.