Access SQLite Database in Swift

I am looking for a way to access an SQLite database in my application using Swift code.

I know that I can use SQLite Wrapper in Objective-C and use the bridge title, but I would prefer to make this project completely in Swift. Is there a way to do this, if so, can someone point me to a link that shows how to send a request, get strings, etc.?

+101
sqlite swift
Jun 08
source share
12 answers

Although you should probably use one of the many SQLite shells (I prefer FMDB myself ), if you want to know how to invoke the SQLite library yourself, you would:

  1. Configure your Swift project to handle SQLite C calls. If you are using Xcode 9, you can simply do:

    import SQLite3 

    In earlier versions of Xcode, you can:

    • Create a bridge header file for the project. See “Importing Objective-C into Swift” under “ Using Swift with cocoa and Objective-C” . This connecting header should import sqlite3.h :

       #import <sqlite3.h> 
    • Add libsqlite3.tbd (or for older versions of libsqlite3.dylib ) to your project:

      enter image description here

  2. Create / open a database.

     let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) .appendingPathComponent("test.sqlite") // open database var db: OpaquePointer? if sqlite3_open(fileURL.path, &db) != SQLITE_OK { print("error opening database") } 
  3. Use sqlite3_exec to execute SQL (e.g. create a table).

     if sqlite3_exec(db, "create table if not exists test (id integer primary key autoincrement, name text)", nil, nil, nil) != SQLITE_OK { let errmsg = String(cString: sqlite3_errmsg(db)!) print("error creating table: \(errmsg)") } 
  4. Use sqlite3_prepare_v2 to prepare SQL with ? placeholder with which we will associate the value.

     var statement: OpaquePointer? if sqlite3_prepare_v2(db, "insert into test (name) values (?)", -1, &statement, nil) != SQLITE_OK { let errmsg = String(cString: sqlite3_errmsg(db)!) print("error preparing insert: \(errmsg)") } if sqlite3_bind_text(statement, 1, "foo", -1, SQLITE_TRANSIENT) != SQLITE_OK { let errmsg = String(cString: sqlite3_errmsg(db)!) print("failure binding foo: \(errmsg)") } if sqlite3_step(statement) != SQLITE_DONE { let errmsg = String(cString: sqlite3_errmsg(db)!) print("failure inserting foo: \(errmsg)") } 

    Please note that the constant SQLITE_TRANSIENT which can be implemented as follows:

     internal let SQLITE_STATIC = unsafeBitCast(0, to: sqlite3_destructor_type.self) internal let SQLITE_TRANSIENT = unsafeBitCast(-1, to: sqlite3_destructor_type.self) 
  5. Reset SQL to insert another value. In this example, I NULL value:

     if sqlite3_reset(statement) != SQLITE_OK { let errmsg = String(cString: sqlite3_errmsg(db)!) print("error resetting prepared statement: \(errmsg)") } if sqlite3_bind_null(statement, 1) != SQLITE_OK { let errmsg = String(cString: sqlite3_errmsg(db)!) print("failure binding null: \(errmsg)") } if sqlite3_step(statement) != SQLITE_DONE { let errmsg = String(cString: sqlite3_errmsg(db)!) print("failure inserting null: \(errmsg)") } 
  6. Complete the prepared statement to recover the memory associated with this prepared statement:

     if sqlite3_finalize(statement) != SQLITE_OK { let errmsg = String(cString: sqlite3_errmsg(db)!) print("error finalizing prepared statement: \(errmsg)") } statement = nil 
  7. Prepare a new statement to select values ​​from the table and run a cycle of extracting values:

     if sqlite3_prepare_v2(db, "select id, name from test", -1, &statement, nil) != SQLITE_OK { let errmsg = String(cString: sqlite3_errmsg(db)!) print("error preparing select: \(errmsg)") } while sqlite3_step(statement) == SQLITE_ROW { let id = sqlite3_column_int64(statement, 0) print("id = \(id); ", terminator: "") if let cString = sqlite3_column_text(statement, 1) { let name = String(cString: cString) print("name = \(name)") } else { print("name not found") } } if sqlite3_finalize(statement) != SQLITE_OK { let errmsg = String(cString: sqlite3_errmsg(db)!) print("error finalizing prepared statement: \(errmsg)") } statement = nil 
  8. Close the database:

     if sqlite3_close(db) != SQLITE_OK { print("error closing database") } db = nil 

For Swift 2, see the previous version of this answer .

+134
Feb 21 '15 at 4:59
source share

The best you can do is import the dynamic library inside the bridge header:

  • Add libsqlite3.dylib to the build phase of Link Binary With Libraries.
  • Create "Bridging-Header.h" and add #import <sqlite3.h> to the top
  • set "Bridging-Header.h" for the parameter "Objective-C Bridging Header" in the build settings in the "Swift Compiler - Code Generation" section

Then you can access all c methods, for example sqlite3_open , from your quick code.

However, you can simply use FMDB and import it through the bridge header, as it is a more object-oriented sqlite shell. Working with C pointers and structures will be cumbersome in Swift.

+18
Jun 08 '14 at 17:17
source share

I also looked for a way to interact with SQLite in the same way as before, in Objective-C. Admittedly, due to C compatibility, I just used the direct C API.

Since there is no wrapper for SQLite in Swift, and the SQLiteDB code mentioned above is at a slightly higher level and involves some use, I decided to create a wrapper and learn a little about Swift in this process. You can find it here: https://github.com/chrismsimpson/SwiftSQLite .

 var db = SQLiteDatabase(); db.open("/path/to/database.sqlite"); var statement = SQLiteStatement(database: db); if ( statement.prepare("SELECT * FROM tableName WHERE Id = ?") != .Ok ) { /* handle error */ } statement.bindInt(1, value: 123); if ( statement.step() == .Row ) { /* do something with statement */ var id:Int = statement.getIntAt(0) var stringValue:String? = statement.getStringAt(1) var boolValue:Bool = statement.getBoolAt(2) var dateValue:NSDate? = statement.getDateAt(3) } statement.finalizeStatement(); /* not called finalize() due to destructor/language keyword */ 
+11
Jul 15 '14 at 0:05
source share

I created an elegant SQLite library written entirely in Swift called SwiftData .

Some of its features:

  • Convenient binding of objects with a SQL string
  • Transaction and savepoint support
  • Integrated error handling
  • Fully thread safe by default

It provides an easy way to make “changes” (for example, INSERT, UPDATE, DELETE, etc.):

 if let err = SD.executeChange("INSERT INTO Cities (Name, Population, IsWarm, FoundedIn) VALUES ('Toronto', 2615060, 0, '1793-08-27')") { //there was an error during the insert, handle it here } else { //no error, the row was inserted successfully } 

and "queries" (e.g. SELECT):

 let (resultSet, err) = SD.executeQuery("SELECT * FROM Cities") if err != nil { //there was an error during the query, handle it here } else { for row in resultSet { if let name = row["Name"].asString() { println("The City name is: \(name)") } if let population = row["Population"].asInt() { println("The population is: \(population)") } if let isWarm = row["IsWarm"].asBool() { if isWarm { println("The city is warm") } else { println("The city is cold") } } if let foundedIn = row["FoundedIn"].asDate() { println("The city was founded in: \(foundedIn)") } } } 

Along with many other features!

You can check it out here.

+5
Aug 25 '14 at 20:34
source share

AppDelegate.swift

 func createDatabase() { var path:Array=NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true) let directory:String=path[0] let DBpath=(directory as NSString).appendingPathComponent("Food.sqlite") print(DBpath) if (FileManager.default.fileExists(atPath: DBpath)) { print("Successfull database create") } else { let pathfrom:String=(Bundle.main.resourcePath! as NSString).appendingPathComponent("Food.sqlite") var success:Bool do { try FileManager.default.copyItem(atPath: pathfrom, toPath: DBpath) success = true } catch _ { success = false } if !success { print("database not create ") } else { print("Successfull database new create") } } } 

Database.swift

 import UIKit class database: NSObject { func databasePath() -> NSString { var path:Array=NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true) let directory:String=path[0] let DBpath=(directory as NSString).appendingPathComponent("Food.sqlite") if (FileManager.default.fileExists(atPath: DBpath)) { return DBpath as NSString } return DBpath as NSString } func ExecuteQuery(_ str:String) -> Bool { var result:Bool=false let DBpath:String=self.databasePath() as 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) { 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>>=[] let DBpath:String=self.databasePath() as 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!) //let rValue=String(cString: UnsafePointer<Int8>(strV!)) dict[rFiled] = rValue i += 1 } result.insert(dict, at: result.count) } sqlite3_finalize(stmt) } sqlite3_close(db) } return result } func AllSelectQuery(_ str:String) -> Array<Model> { var result:Array<Model>=[] let DBpath:String=self.databasePath() as 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) { let mod=Model() mod.id=String(cString: sqlite3_column_text(stmt, 0)) mod.image=String(cString: sqlite3_column_text(stmt, 1)) mod.name=String(cString: sqlite3_column_text(stmt, 2)) mod.foodtype=String(cString: sqlite3_column_text(stmt, 3)) mod.vegtype=String(cString: sqlite3_column_text(stmt, 4)) mod.details=String(cString: sqlite3_column_text(stmt, 5)) result.insert(mod, at: result.count) } sqlite3_finalize(stmt) } sqlite3_close(db) } return result } } 

Model.swift

 import UIKit class Model: NSObject { var uid:Int = 0 var id:String = "" var image:String = "" var name:String = "" var foodtype:String = "" var vegtype:String = "" var details:String = "" var mealtype:String = "" var date:String = "" } 

Access to the database:

 let DB=database() var mod=Model() 

Fire Request Database:

 var DailyResult:Array<Model> = DB.AllSelectQuery("select * from food where foodtype == 'Sea Food' ORDER BY name ASC") 
+3
Nov 10 '16 at 4:25
source share

Another SQLite wrapper for Swift 2 and Swift 3: http://github.com/groue/GRDB.swift

Features:

  • An API that will look familiar to ccgus / fmdb users

  • Low-level SQLite API that uses the standard Swift library

  • Pretty fast query interface for SQL allergy developers

  • SQLite WAL mode support and simultaneous database access for added performance

  • A record class that wraps the result sets, eats your custom SQL breakfast queries, and provides basic CRUD operations

  • Free Freedom: Choose the right Swift type to suit your data. Use Int64 if necessary, or stick with a convenient Int. Store and read NSDate or NSDateComponents. Declare Swift enumerations for discrete data types. Define your own types of convertible databases.

  • Database migrations

  • Speed: https://github.com/groue/GRDB.swift/wiki/Performance

+2
Aug 18 '15 at 6:33
source share

I wrote a SQLite3 wrapper library written in Swift .

This is actually a very high-level shell with a very simple API, but in any case it has a low-level C code, and I post here a (simplified) part of it to show the C-operator.

  struct C { static let NULL = COpaquePointer.null() } func open(filename:String, flags:OpenFlag) { let name2 = filename.cStringUsingEncoding(NSUTF8StringEncoding)! let r = sqlite3_open_v2(name2, &_rawptr, flags.value, UnsafePointer<Int8>.null()) checkNoErrorWith(resultCode: r) } func close() { let r = sqlite3_close(_rawptr) checkNoErrorWith(resultCode: r) _rawptr = C.NULL } func prepare(SQL:String) -> (statements:[Core.Statement], tail:String) { func once(zSql:UnsafePointer<Int8>, len:Int32, inout zTail:UnsafePointer<Int8>) -> Core.Statement? { var pStmt = C.NULL let r = sqlite3_prepare_v2(_rawptr, zSql, len, &pStmt, &zTail) checkNoErrorWith(resultCode: r) if pStmt == C.NULL { return nil } return Core.Statement(database: self, pointerToRawCStatementObject: pStmt) } var stmts:[Core.Statement] = [] let sql2 = SQL as NSString var zSql = UnsafePointer<Int8>(sql2.UTF8String) var zTail = UnsafePointer<Int8>.null() var len1 = sql2.lengthOfBytesUsingEncoding(NSUTF8StringEncoding); var maxlen2 = Int32(len1)+1 while let one = once(zSql, maxlen2, &zTail) { stmts.append(one) zSql = zTail } let rest1 = String.fromCString(zTail) let rest2 = rest1 == nil ? "" : rest1! return (stmts, rest2) } func step() -> Bool { let rc1 = sqlite3_step(_rawptr) switch rc1 { case SQLITE_ROW: return true case SQLITE_DONE: return false default: database.checkNoErrorWith(resultCode: rc1) } } func columnText(at index:Int32) -> String { let bc = sqlite3_column_bytes(_rawptr, Int32(index)) let cs = sqlite3_column_text(_rawptr, Int32(index)) let s1 = bc == 0 ? "" : String.fromCString(UnsafePointer<CChar>(cs))! return s1 } func finalize() { let r = sqlite3_finalize(_rawptr) database.checkNoErrorWith(resultCode: r) _rawptr = C.NULL } 

If you want to get the full source code of this low-level shell, see these files.

0
Sep 21 '14 at
source share

Set up your Swift project to handle SQLite C calls:

Create a header file header in the project. See the Importing Objective-C into Swift section of Using Swift with Cocoa and Objective-C. This bridge header should import sqlite3.h:

Add libsqlite3.0.dylib to your project. See the Apple documentation for adding a library / framework to a single project.

and the following code is used

  func executeQuery(query: NSString ) -> Int { if sqlite3_open(databasePath! as String, &database) != SQLITE_OK { println("Databse is not open") return 0 } else { query.stringByReplacingOccurrencesOfString("null", withString: "") var cStatement:COpaquePointer = nil var executeSql = query as NSString var lastId : Int? var sqlStatement = executeSql.cStringUsingEncoding(NSUTF8StringEncoding) sqlite3_prepare_v2(database, sqlStatement, -1, &cStatement, nil) var execute = sqlite3_step(cStatement) println("\(execute)") if execute == SQLITE_DONE { lastId = Int(sqlite3_last_insert_rowid(database)) } else { println("Error in Run Statement :- \(sqlite3_errmsg16(database))") } sqlite3_finalize(cStatement) return lastId! } } func ViewAllData(query: NSString, error: NSError) -> NSArray { var cStatement = COpaquePointer() var result : AnyObject = NSNull() var thisArray : NSMutableArray = NSMutableArray(capacity: 4) cStatement = prepare(query) if cStatement != nil { while sqlite3_step(cStatement) == SQLITE_ROW { result = NSNull() var thisDict : NSMutableDictionary = NSMutableDictionary(capacity: 4) for var i = 0 ; i < Int(sqlite3_column_count(cStatement)) ; i++ { if sqlite3_column_type(cStatement, Int32(i)) == 0 { continue } if sqlite3_column_decltype(cStatement, Int32(i)) != nil && strcasecmp(sqlite3_column_decltype(cStatement, Int32(i)), "Boolean") == 0 { var temp = sqlite3_column_int(cStatement, Int32(i)) if temp == 0 { result = NSNumber(bool : false) } else { result = NSNumber(bool : true) } } else if sqlite3_column_type(cStatement,Int32(i)) == SQLITE_INTEGER { var temp = sqlite3_column_int(cStatement,Int32(i)) result = NSNumber(int : temp) } else if sqlite3_column_type(cStatement,Int32(i)) == SQLITE_FLOAT { var temp = sqlite3_column_double(cStatement,Int32(i)) result = NSNumber(double: temp) } else { if sqlite3_column_text(cStatement, Int32(i)) != nil { var temp = sqlite3_column_text(cStatement,Int32(i)) result = String.fromCString(UnsafePointer<CChar>(temp))! var keyString = sqlite3_column_name(cStatement,Int32(i)) thisDict.setObject(result, forKey: String.fromCString(UnsafePointer<CChar>(keyString))!) } result = NSNull() } if result as! NSObject != NSNull() { var keyString = sqlite3_column_name(cStatement,Int32(i)) thisDict.setObject(result, forKey: String.fromCString(UnsafePointer<CChar>(keyString))!) } } thisArray.addObject(NSMutableDictionary(dictionary: thisDict)) } sqlite3_finalize(cStatement) } return thisArray } func prepare(sql : NSString) -> COpaquePointer { var cStatement:COpaquePointer = nil sqlite3_open(databasePath! as String, &database) var utfSql = sql.UTF8String if sqlite3_prepare(database, utfSql, -1, &cStatement, nil) == 0 { sqlite3_close(database) return cStatement } else { sqlite3_close(database) return nil } } } 
0
May 15 '15 at 12:29
source share

Sometimes a quick version of "SQLite in 5 minutes or less" shown on sqlite.org . The "5 minutes or less" approach uses sqlite3_exec() , which is a convenient wrapper for sqlite3_prepare() , sqlite3_step() , sqlite3_column() and sqlite3_finalize() .

Swift 2.2 can directly support the sqlite3_exec() callback function pointer as a global, non-instance func procedure, or a non-literal literal closure {} .

typealias

 typealias sqlite3 = COpaquePointer typealias CCharHandle = UnsafeMutablePointer<UnsafeMutablePointer<CChar>> typealias CCharPointer = UnsafeMutablePointer<CChar> typealias CVoidPointer = UnsafeMutablePointer<Void> 

Callback approach

 func callback( resultVoidPointer: CVoidPointer, // void *NotUsed columnCount: CInt, // int argc values: CCharHandle, // char **argv columns: CCharHandle // char **azColName ) -> CInt { for i in 0 ..< Int(columnCount) { guard let value = String.fromCString(values[i]) else { continue } guard let column = String.fromCString(columns[i]) else { continue } print("\(column) = \(value)") } return 0 // status ok } func sqlQueryCallbackBasic(argc: Int, argv: [String]) -> Int { var db: sqlite3 = nil var zErrMsg:CCharPointer = nil var rc: Int32 = 0 // result code if argc != 3 { print(String(format: "ERROR: Usage: %s DATABASE SQL-STATEMENT", argv[0])) return 1 } rc = sqlite3_open(argv[1], &db) if rc != 0 { print("ERROR: sqlite3_open " + String.fromCString(sqlite3_errmsg(db))! ?? "" ) sqlite3_close(db) return 1 } rc = sqlite3_exec(db, argv[2], callback, nil, &zErrMsg) if rc != SQLITE_OK { print("ERROR: sqlite3_exec " + String.fromCString(zErrMsg)! ?? "") sqlite3_free(zErrMsg) } sqlite3_close(db) return 0 } 

Closure Approach

 func sqlQueryClosureBasic(argc argc: Int, argv: [String]) -> Int { var db: sqlite3 = nil var zErrMsg:CCharPointer = nil var rc: Int32 = 0 if argc != 3 { print(String(format: "ERROR: Usage: %s DATABASE SQL-STATEMENT", argv[0])) return 1 } rc = sqlite3_open(argv[1], &db) if rc != 0 { print("ERROR: sqlite3_open " + String.fromCString(sqlite3_errmsg(db))! ?? "" ) sqlite3_close(db) return 1 } rc = sqlite3_exec( db, // database argv[2], // statement { // callback: non-capturing closure resultVoidPointer, columnCount, values, columns in for i in 0 ..< Int(columnCount) { guard let value = String.fromCString(values[i]) else { continue } guard let column = String.fromCString(columns[i]) else { continue } print("\(column) = \(value)") } return 0 }, nil, &zErrMsg ) if rc != SQLITE_OK { let errorMsg = String.fromCString(zErrMsg)! ?? "" print("ERROR: sqlite3_exec \(errorMsg)") sqlite3_free(zErrMsg) } sqlite3_close(db) return 0 } 

To prepare an Xcode project to invoke a C library, such as SQLite, you must (1) add a link to the Bridging-Header.h file. C headers such as #import "sqlite3.h" , (2) add Bridging-Header.h to the Objective-C Bridging Header in the project settings and (3) add the libsqlite3.tbd settings to Link Binary With Library .

sqlite.org "SQLite in 5 minutes or less" is implemented in the Swift Xcode7 project here .

0
Jun 05 '16 at 6:47
source share

You can easily customize SQLite with swift using a single ton class.

Cm

https://github.com/hasyapanchasara/SQLite_SingleManagerClass

The way to create a database

 func methodToCreateDatabase() -> NSURL?{} 

The way to insert, update and delete data

 func methodToInsertUpdateDeleteData(strQuery : String) -> Bool{} 

Data selection method

 func methodToSelectData(strQuery : String) -> NSMutableArray{} 
0
Mar 17 '17 at 13:48 on
source share

You can use this library in Swift for SQLite https://github.com/pmurphyjam/SQLiteDemo

SQLiteDemo

SQLite Demo using Swift with SQLDataAccess class written in Swift

Adding to the project

You only need three files to add to your project * SQLDataAccess.swift * DataConstants.swift * Bridges-Header.h Bridging-Header must be installed in your Xcode project 'Objective-C Bridging Header' in the section 'Swift Compiler - General'

Examples of using

Just follow the code in ViewController.swift to learn how to write simple SQL using SQLDataAccess.swift First you need to open the SQLite database, which deals with

 ```swift let db = SQLDataAccess.shared db.setDBName(name:"SQLite.db") let opened = db.openConnection(copyFile:true) ``` 

If openConnection succeeded, now you can do a simple insertion into the AppInfo table

 ```swift //Insert into Table AppInfo let status = db.executeStatement("insert into AppInfo (name,value,descrip,date) values(?,?,?,?)", "SQLiteDemo","1.0.2","unencrypted",Date()) if(status) { //Read Table AppInfo into an Array of Dictionaries let results = db.getRecordsForQuery("select * from AppInfo ") NSLog("Results = \(results)") } ``` 

See how it was!

The first term in db.executeStatement is your SQL as a String, all of the following terms are a list of variational arguments of type Any and are your parameters in the array. All of these terms are separated by commas in your list of SQL arguments. You can enter strings, integers, dates and flags immediately after the sequel is approved, since all these terms are considered parameters for the sequel. An array of variational arguments just makes it convenient to enter your entire sequel with just one call to executeStatement or getRecordsForQuery. If you do not have any parameters, do not enter anything after your SQL.

The result array is an array of dictionaries, where "key" is the name of the table column and "value is your data retrieved from SQLite." You can easily iterate over this array using the for loop or print it directly or assign these dictionary elements to custom data classes that you use in View controllers to consume the model.

 ```swift for dic in results as! [[String:AnyObject]] { print("result = \(dic)") } ``` 

SQLDataAccess will store text, double, float, blob, Date, integer and long long integers. For blobs you can store binary, varbinary, blob.

For text, you can save char, character, clob, national distinguished character, native character, nchar, nvarchar, varchar, variant, variable character, text.

In the "Dates" field you can store the date and time, time, time stamp, date.

For integers, you can store bigint, bit, bool, boolean, int2, int8, integer, mediumint, smallint, tinyint, int.

For doubles, you can store decimal, double precision, float, numeric, real, double. The double has the greatest accuracy.

You can even store Nulls like Null.

ViewController.swift runs a more sophisticated example, showing how to insert a dictionary as a "Blob". In addition, SQLDataAccess understands the native Swift Date (), so you can insert these objects without conversion and convert them to text and save them, and when extracted, convert them back from text to Date.

Of course, the real power of SQLite is the ability of a transaction. Here you can literally queue 400 SQL statements with parameters and insert them all at once, which is very effective, since it is so fast. ViewController.swift also shows you an example of how to do this. All you really do is create an array of dictionaries called "sqlAndParams", this array stores dictionaries with two "SQL" keys for a statement or query for String and "PARAMS" syntax, which is just an array of native objects that SQLite understands for this request. "sqlParams", , "sqlAndParams". , .

 ```swift let status = db.executeTransaction(sqlAndParams) if(status) { //Read Table AppInfo into an Array of Dictionaries for the above Transactions let results = db.getRecordsForQuery("select * from AppInfo ") NSLog("Results = \(results)") } ``` 

, executeStatement getRecordsForQuery String SQL , .

 ```swift let sql : String = "insert into AppInfo (name,value,descrip) values(?,?,?)" let params : Array = ["SQLiteDemo","1.0.0","unencrypted"] let status = db.executeStatement(sql, withParameters: params) if(status) { //Read Table AppInfo into an Array of Dictionaries for the above Transactions let results = db.getRecordsForQuery("select * from AppInfo ") NSLog("Results = \(results)") } ``` 

Objective-C SQLDataAccess, Objective-C Swift. , SQLDataAccess SQLCipher, , , , , Objective-C SQLDataAccess.

SQLDataAccess CoreData, SQLite CoreData, CoreData.

0
22 . '17 20:21
source share

Sqlite, Swift: https://github.com/stephencelis/SQLite.swift

. , C API:

 import SQLite let db = try Connection("path/to/db.sqlite3") let users = Table("users") let id = Expression<Int64>("id") let name = Expression<String?>("name") let email = Expression<String>("email") try db.run(users.create { t in t.column(id, primaryKey: true) t.column(name) t.column(email, unique: true) }) // CREATE TABLE "users" ( // "id" INTEGER PRIMARY KEY NOT NULL, // "name" TEXT, // "email" TEXT NOT NULL UNIQUE // ) let insert = users.insert(name <- "Alice", email <- "alice@mac.com") let rowid = try db.run(insert) // INSERT INTO "users" ("name", "email") VALUES ('Alice', 'alice@mac.com') for user in try db.prepare(users) { print("id: \(user[id]), name: \(user[name]), email: \(user[email])") // id: 1, name: Optional("Alice"), email: alice@mac.com } // SELECT * FROM "users" let alice = users.filter(id == rowid) try db.run(alice.update(email <- email.replace("mac.com", with: "me.com"))) // UPDATE "users" SET "email" = replace("email", 'mac.com', 'me.com') // WHERE ("id" = 1) try db.run(alice.delete()) // DELETE FROM "users" WHERE ("id" = 1) try db.scalar(users.count) // 0 // SELECT count(*) FROM "users" 

, "SQLite.swift , Swift C API", .

0
20 . '19 19:22
source share



All Articles