Доступ к базе данных SQLite в Swift

Я ищу способ получить доступ к базе данных SQLite в моем приложении с помощью кода Swift.

Я знаю, что я могу использовать SQLite Wrapper в Objective C и использовать заголовок моста, но я предпочел бы полностью реализовать этот проект в Swift. Есть ли способ сделать это, если да, может ли кто-нибудь указать мне ссылку, которая показывает, как отправить запрос, получить строки и т. Д.?

Хотя вы, вероятно, должны использовать одну из многих оболочек SQLite (я предпочитаю FMDB , я сам), если вы хотите знать, как вызвать библиотеку SQLite самостоятельно, вы бы:

  1. Настройте свой проект Swift для обработки вызовов SQLite C. Если вы используете Xcode 9, вы можете просто:

    import SQLite3 

    В более ранних версиях Xcode вы можете:

    • Создайте в проект заголовок заголовочного файла. См. Раздел Импортирование Objective-C в Swift с помощью Swift с Cocoa и Objective-C . Этот заголовок моста должен импортировать sqlite3.h :

       #import  
    • Добавьте libsqlite3.tbd (или еще более старые версии, libsqlite3.dylib ) в ваш проект:

      введите описание изображения здесь

  2. Создать / открыть базу данных.

     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. Используйте sqlite3_exec для выполнения SQL (например, создать таблицу).

     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. Используйте sqlite3_prepare_v2 для подготовки SQL ? который будет привязан к значению.

     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)") } 

    Обратите внимание, что используется константа SQLITE_TRANSIENT которая может быть реализована следующим образом:

     internal let SQLITE_STATIC = unsafeBitCast(0, to: sqlite3_destructor_type.self) internal let SQLITE_TRANSIENT = unsafeBitCast(-1, to: sqlite3_destructor_type.self) 
  5. Сбросьте SQL, чтобы вставить другое значение. В этом примере я добавлю значение NULL :

     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. Завершите подготовленный оператор для восстановления памяти, связанной с этим подготовленным оператором:

     if sqlite3_finalize(statement) != SQLITE_OK { let errmsg = String(cString: sqlite3_errmsg(db)!) print("error finalizing prepared statement: \(errmsg)") } statement = nil 
  7. Подготовьте новый оператор для выбора значений из таблицы и цикла путем извлечения значений:

     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. Закрыть базу данных:

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

Для Swift 2 см. Предыдущую ревизию этого ответа .

Лучшее, что вы можете сделать, это импортировать динамическую библиотеку внутри заголовка моста:

  1. Добавьте libsqlite3.dylib в фазу сборки Link Binary With Libraries
  2. Создайте «Bridging-Header.h» и добавьте #import в начало
  3. установите «Bridging-Header.h» для параметра «Objective-C Bridging Header» в настройках сборки в разделе «Swift Compiler – Code Generation»

Затем вы сможете получить доступ ко всем c-методам, например sqlite3_open из вашего быстрого кода.

Однако вы можете просто хотеть использовать FMDB и импортировать его через заголовок моста, поскольку это более объектно-ориентированная shell sqlite. Работа с C-указателями и структурами будет громоздкой в ​​Swift.

Я тоже искал способ взаимодействия с SQLite так же, как и раньше, в Objective-C. По общему признанию, из-за совместимости с C я просто использовал прямой C API.

Поскольку в SQLite в Swift не существует обертки, а упомянутый выше код SQLiteDB имеет несколько более высокий уровень и предполагает определенное использование, я решил создать оболочку и немного узнать о Swift в этом процессе. Вы можете найти его здесь: 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 */ 

Я создал элегантную библиотеку SQLite, написанную полностью в Swift под названием SwiftData .

Некоторые из его функций:

  • Привязать объекты к строке SQL
  • Поддержка транзакций и точек сохранения
  • Встроенная обработка ошибок
  • Полностью streamобезопасный по умолчанию

Он обеспечивает простой способ выполнения «изменений» (например, INSERT, UPDATE, DELETE и т. Д.):

 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 } 

и «запросы» (например, 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)") } } } 

Наряду со многими другими функциями!

Вы можете проверить это здесь

Еще одна shell SQLite для Swift 2 и Swift 3: http://github.com/groue/GRDB.swift

Особенности:

  • API, который будет выглядеть знакомым пользователям ccgus / fmdb

  • Низкоуровневый SQLite API, который использует стандартную библиотеку Swift

  • Довольно быстрый интерфейс запросов для SQL-аллергенных разработчиков

  • Поддержка режима SQLite WAL и одновременный доступ к базе данных для повышения производительности

  • Класс записи, который обертывает результирующие наборы, ест ваши пользовательские SQL-запросы на завтрак и предоставляет базовые операции CRUD

  • Свободная свобода: выберите правильный тип Swift, который соответствует вашим данным. Используйте Int64, если необходимо, или придерживайтесь удобного Int. Храните и читайте NSDate или NSDateComponents. Объявить Swift enums для дискретных типов данных. Определите свои собственные типы конвертируемых баз данных.

  • Миграции баз данных

  • Скорость: https://github.com/groue/GRDB.swift/wiki/Performance

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> { var result:Array>=[] 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() 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(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 { var result:Array=[] 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 = "" } 

Доступ к базе данных:

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

firebase database Запрос огня:

 var DailyResult:Array = DB.AllSelectQuery("select * from food where foodtype == 'Sea Food' ORDER BY name ASC") 

Я написал библиотеку оболочек SQLite3, написанную в Swift .

На самом деле это очень высокоуровневая shell с очень простым API, но в любом случае у нее есть низкоуровневый C-код, и я размещаю здесь (упрощенную) часть его, чтобы показать C-оператор.

  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.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, len:Int32, inout zTail:UnsafePointer) -> 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(sql2.UTF8String) var zTail = UnsafePointer.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(cs))! return s1 } func finalize() { let r = sqlite3_finalize(_rawptr) database.checkNoErrorWith(resultCode: r) _rawptr = C.NULL } 

Если вы хотите получить полный исходный код этой низкоуровневой оболочки, см. Эти файлы.

Настройте свой проект Swift для обработки вызовов SQLite C:

Создайте в проект заголовок заголовочного файла. См. Раздел Импортирование Objective-C в Swift с помощью Swift с Cocoa и Objective-C. Этот заголовок моста должен импортировать sqlite3.h:

Добавьте libsqlite3.0.dylib в свой проект. См. Документацию Apple относительно добавления библиотеки / frameworks в свой проект.

и используется следующий код

  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(temp))! var keyString = sqlite3_column_name(cStatement,Int32(i)) thisDict.setObject(result, forKey: String.fromCString(UnsafePointer(keyString))!) } result = NSNull() } if result as! NSObject != NSNull() { var keyString = sqlite3_column_name(cStatement,Int32(i)) thisDict.setObject(result, forKey: String.fromCString(UnsafePointer(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 } } } 

Иногда достаточно быстрой версии подхода «SQLite за 5 минут или меньше», показанного на sqlite.org . Подход «5 минут или меньше» использует sqlite3_exec() который является удобной оболочкой для sqlite3_prepare() , sqlite3_step() , sqlite3_column() и sqlite3_finalize() .

Swift 2.2 может напрямую поддерживать указатель функции callback sqlite3_exec() как глобальную, не экземпляр процедуры func или не захватывающее литеральное закрытие {} .

Читаемые typealias

 typealias sqlite3 = COpaquePointer typealias CCharHandle = UnsafeMutablePointer> typealias CCharPointer = UnsafeMutablePointer typealias CVoidPointer = UnsafeMutablePointer 

Обратный подход

 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 } 

Подход к закрытию

 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 } 

Чтобы подготовить проект Xcode для вызова библиотеки C, такой как SQLite, необходимо (1) добавить ссылку на файл Bridging-Header.h. Заголовки C, такие как #import "sqlite3.h" , (2) добавить Bridging-Header.h в Objective-C Bridging Header в настройках проекта и (3) добавить libsqlite3.tbd для libsqlite3.tbd к настройкам библиотеки .

Пример sqlite.org «SQLite за 5 минут или меньше» реализован здесь в проекте Swift Xcode7.

Вы можете легко настроить SQLite с помощью swift с использованием одного тонного classа.

обращаться

https://github.com/hasyapanchasara/SQLite_SingleManagerClass

Способ создания базы данных

 func methodToCreateDatabase() -> NSURL?{} 

Способ вставки, обновления и удаления данных

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

Способ выбора данных

 func methodToSelectData(strQuery : String) -> NSMutableArray{} 

Вы можете использовать эту библиотеку в Swift для SQLite https://github.com/pmurphyjam/SQLiteDemo

SQLiteDemo

SQLite Demo с использованием Swift с classом SQLDataAccess, написанным в Swift

Добавление в проект

Вам нужно всего три файла для добавления в ваш проект * SQLDataAccess.swift * DataConstants.swift * Bridging-Header.h Bridging-Header должен быть установлен в вашем проекте Xcode ‘Objective-C Bridging Header’ в разделе ‘Swift Compiler – General’

Примеры использования

Просто следуйте коду в ViewController.swift, чтобы узнать, как писать простой SQL с помощью SQLDataAccess.swift. Сначала вам нужно открыть базу данных SQLite, с которой вы работаете

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

Если openConnection удалось, теперь вы можете сделать простую вставку в таблицу AppInfo

 ```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)") } ``` 

Посмотрите, насколько это было!

Первым термином в db.executeStatement является ваш SQL как String, все последующие термины являются вариационным списком аргументов типа Any и являются вашими параметрами в массиве. Все эти термины разделяются запятыми в вашем списке аргументов SQL. Вы можете вводить строки, целые числа, даты и блабы сразу после утверждения сиквела, поскольку все эти термины считаются параметрами сиквела. Массив вариационных аргументов просто делает его удобным для ввода всего вашего сиквела только одним вызовом executeStatement или getRecordsForQuery. Если у вас нет каких-либо параметров, не вводите ничего после своего SQL.

Массив результатов – это массив словарей, где «ключ» – это имя столбца таблиц, а «значение» – ваши данные, полученные из SQLite. Вы можете легко выполнить итерацию через этот массив с помощью цикла for или распечатать его напрямую или присвоить этим элементам словаря пользовательские объекты classа данных, которые вы используете в своих controllerах View для потребления модели.

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

SQLDataAccess будет хранить, текст, двойной, float, blob, Date, integer и long long integers. Для Blobs вы можете хранить двоичные, varbinary, blob.

Для текста вы можете хранить символ, символ, clob, национальный различающийся символ, собственный характер, nchar, nvarchar, varchar, вариант, различный символ, текст.

Для дат вы можете хранить дату и время, время, метку времени, дату.

Для целых чисел вы можете хранить bigint, bit, bool, boolean, int2, int8, integer, mediumint, smallint, tinyint, int.

Для парного разряда вы можете хранить десятичную, двойную точность, поплавок, числовые, реальные, двойные. Двойная точность.

Вы даже можете хранить Nulls типа Null.

В ViewController.swift выполняется более сложный пример, показывающий, как вставить словарь как «Blob». Кроме того, SQLDataAccess понимает родную Swift Date (), поэтому вы можете вставлять эти объекты без преобразования, и они преобразуют их в текст и сохраняют их, а при их восстановлении преобразуют их обратно из текста в Date.

Разумеется, реальная сила SQLite – это способность транзакции. Здесь вы можете буквально поставить в очередь 400 операторов SQL с параметрами и вставить их сразу, что очень эффективно, так как это так быстро. ViewController.swift также показывает вам пример того, как это сделать. Все, что вы действительно делаете, это создание массива словарей под названием «sqlAndParams», в этом массиве хранятся словари с двумя ключами «SQL» для инструкции или запроса синтаксиса String и «PARAMS», который является всего лишь массивом собственных объектов SQLite понимает этот запрос. Каждый «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 for 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 – очень быстрый и эффективный class и может использоваться вместо CoreData, который на самом деле просто использует SQLite, поскольку он находится в основе хранилища данных, без всех сбоев в сбое целостности ядра CoreData, которые поставляются с CoreData.

  • Общий форум
  • Быстрые константы: Struct или Enum
  • UIApplication.registerForRemoteNotifications () необходимо вызывать только из основного streamа
  • SHA256 в быстрой
  • NSFontAttributedString работал до XCode 6.1
  • Как сериализовать или преобразовать объекты Swift в JSON?
  • Перенаправить NSLog в файл в Swift не работает
  • Граница UITextField для нижней стороны
  • Получить пользовательскую версию имени classа в swift (в objc NSStringFromClass было хорошо)
  • Хранить в NSUserDefaults
  • Генерирование случайных чисел с помощью Swift
  • Давайте будем гением компьютера.