Accéder à une firebase database SQLite dans Swift

Je cherche un moyen d’accéder à une firebase database SQLite dans mon application avec du code Swift.

Je sais que je peux utiliser un wrapper SQLite dans Objective C et utiliser l’en-tête de pontage, mais je serais plutôt capable de réaliser ce projet entièrement dans Swift. Est-il possible de le faire, si oui, quelqu’un peut-il me diriger vers une référence qui montre comment soumettre une requête, récupérer des lignes, etc.?

Alors que vous devriez probablement utiliser l’un des nombreux wrappers SQLite (je préfère le FMDB moi-même), si vous voulez savoir comment appeler la bibliothèque SQLite vous-même, vous devriez:

  1. Configurez votre projet Swift pour gérer les appels SQLite C. Si vous utilisez Xcode 9, vous pouvez simplement faire:

    import SQLite3 

    Dans les versions antérieures de Xcode, vous pouvez:

    • Créez un fichier d’en-tête de pontage pour le projet. Reportez-vous à la section Importation d’Objective-C dans Swift du chapitre Utilisation de Swift avec Cocoa et Objective-C . Cet en-tête de pontage doit importer sqlite3.h :

       #import  
    • Ajoutez le libsqlite3.tbd (ou même les anciennes versions, libsqlite3.dylib ) à votre projet:

      entrer la description de l'image ici

  2. Créer / ouvrir une firebase 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. Utilisez sqlite3_exec pour effectuer du SQL (par exemple, créer une 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 = Ssortingng(cSsortingng: sqlite3_errmsg(db)!) print("error creating table: \(errmsg)") } 
  4. Utilisez sqlite3_prepare_v2 pour préparer SQL avec ? espace réservé auquel nous lierons la valeur.

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

    Notez que la constante SQLITE_TRANSIENT peut être implémentée comme suit:

     internal let SQLITE_STATIC = unsafeBitCast(0, to: sqlite3_destructor_type.self) internal let SQLITE_TRANSIENT = unsafeBitCast(-1, to: sqlite3_destructor_type.self) 
  5. Réinitialisez SQL pour insérer une autre valeur. Dans cet exemple, je vais insérer une valeur NULL :

     if sqlite3_reset(statement) != SQLITE_OK { let errmsg = Ssortingng(cSsortingng: sqlite3_errmsg(db)!) print("error resetting prepared statement: \(errmsg)") } if sqlite3_bind_null(statement, 1) != SQLITE_OK { let errmsg = Ssortingng(cSsortingng: sqlite3_errmsg(db)!) print("failure binding null: \(errmsg)") } if sqlite3_step(statement) != SQLITE_DONE { let errmsg = Ssortingng(cSsortingng: sqlite3_errmsg(db)!) print("failure inserting null: \(errmsg)") } 
  6. Finaliser l’instruction préparée pour récupérer la mémoire associée à cette instruction préparée:

     if sqlite3_finalize(statement) != SQLITE_OK { let errmsg = Ssortingng(cSsortingng: sqlite3_errmsg(db)!) print("error finalizing prepared statement: \(errmsg)") } statement = nil 
  7. Préparez une nouvelle instruction pour sélectionner des valeurs de table et de boucle en récupérant les valeurs:

     if sqlite3_prepare_v2(db, "select id, name from test", -1, &statement, nil) != SQLITE_OK { let errmsg = Ssortingng(cSsortingng: 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 cSsortingng = sqlite3_column_text(statement, 1) { let name = Ssortingng(cSsortingng: cSsortingng) print("name = \(name)") } else { print("name not found") } } if sqlite3_finalize(statement) != SQLITE_OK { let errmsg = Ssortingng(cSsortingng: sqlite3_errmsg(db)!) print("error finalizing prepared statement: \(errmsg)") } statement = nil 
  8. Fermer la firebase database:

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

Pour Swift 2, voir la révision précédente de cette réponse .

Le mieux que vous puissiez faire est d’importer la bibliothèque dynamic dans un en-tête de pontage:

  1. Ajoutez libsqlite3.dylib à votre phase de génération “Link Binary With Libraries”
  2. Créez un “Bridging-Header.h” et ajoutez #import au début
  3. définir “Bridging-Header.h” pour le paramètre “Objective-C Bridging Header” dans les parameters de construction sous “Swift Comstackr – Génération de code”

Vous pourrez alors accéder à toutes les méthodes c telles que sqlite3_open partir de votre code rapide.

Cependant, vous souhaiterez peut-être simplement utiliser FMDB et l’importer via l’en-tête de pontage car il s’agit d’un wrapper de sqlite plus orienté object. Traiter avec les pointeurs et les structures C sera lourd dans Swift.

Moi aussi, je cherchais un moyen d’interagir avec SQLite de la même manière que j’avais l’habitude de le faire auparavant dans Objective-C. Certes, grâce à la compatibilité C, je viens d’utiliser l’API straight C.

Comme aucun wrapper n’existe actuellement pour SQLite dans Swift et que le code SQLiteDB mentionné ci-dessus passe un peu plus haut et suppose une certaine utilisation, j’ai décidé de créer un wrapper et de me familiariser avec Swift. Vous pouvez le trouver ici: 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 ssortingngValue:Ssortingng? = statement.getSsortingngAt(1) var boolValue:Bool = statement.getBoolAt(2) var dateValue:NSDate? = statement.getDateAt(3) } statement.finalizeStatement(); /* not called finalize() due to destructor/language keyword */ 

J’ai créé une bibliothèque SQLite élégante, entièrement écrite dans Swift, appelée SwiftData .

Certaines de ses fonctionnalités sont les suivantes:

  • Lier les objects commodément à la chaîne de SQL
  • Prise en charge des transactions et des points de sauvegarde
  • Traitement des erreurs en ligne
  • Filtrer complètement sans risque par défaut

Il fournit un moyen facile d’exécuter des “modifications” (par exemple, 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 } 

et ‘requêtes’ (ex: 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"].asSsortingng() { 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)") } } } 

Avec beaucoup plus de fonctionnalités!

Vous pouvez le vérifier ici

Encore un autre wrapper SQLite pour Swift 2 et Swift 3: http://github.com/groue/GRDB.swift

Caractéristiques:

  • Une API qui sera familière aux utilisateurs de ccgus / fmdb

  • Une API SQLite de bas niveau qui exploite la bibliothèque standard Swift

  • Une jolie interface de requête Swift pour les développeurs SQL-allergiques

  • Prise en charge du mode SQLite WAL et access simultané à la firebase database pour des performances supplémentaires

  • Une classe Record qui encapsule les jeux de résultats, mange vos requêtes SQL personnalisées pour le petit-déjeuner et fournit des opérations CRUD de base

  • Liberté de type Swift: choisissez le type Swift adapté à vos données. Utilisez Int64 en cas de besoin ou respectez l’Int. Stockez et lisez NSDate ou NSDateComponents. Déclarez les énumérations Swift pour les types de données discrets. Définissez vos propres types de convertibles de firebase database.

  • Migrations de firebase database

  • Vitesse: 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:Ssortingng=path[0] let DBpath=(directory as NSSsortingng).appendingPathComponent("Food.sqlite") print(DBpath) if (FileManager.default.fileExists(atPath: DBpath)) { print("Successfull database create") } else { let pathfrom:Ssortingng=(Bundle.main.resourcePath! as NSSsortingng).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() -> NSSsortingng { var path:Array=NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true) let directory:Ssortingng=path[0] let DBpath=(directory as NSSsortingng).appendingPathComponent("Food.sqlite") if (FileManager.default.fileExists(atPath: DBpath)) { return DBpath as NSSsortingng } return DBpath as NSSsortingng } func ExecuteQuery(_ str:Ssortingng) -> Bool { var result:Bool=false let DBpath:Ssortingng=self.databasePath() as Ssortingng var db: OpaquePointer? = nil var stmt:OpaquePointer? = nil let strExec=str.cSsortingng(using: Ssortingng.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:Ssortingng) -> Array> { var result:Array>=[] let DBpath:Ssortingng=self.databasePath() as Ssortingng var db: OpaquePointer? = nil var stmt:OpaquePointer? = nil let strExec=str.cSsortingng(using: Ssortingng.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:Ssortingng) -> Array { var result:Array=[] let DBpath:Ssortingng=self.databasePath() as Ssortingng var db: OpaquePointer? = nil var stmt:OpaquePointer? = nil let strExec=str.cSsortingng(using: Ssortingng.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=Ssortingng(cSsortingng: sqlite3_column_text(stmt, 0)) mod.image=Ssortingng(cSsortingng: sqlite3_column_text(stmt, 1)) mod.name=Ssortingng(cSsortingng: sqlite3_column_text(stmt, 2)) mod.foodtype=Ssortingng(cSsortingng: sqlite3_column_text(stmt, 3)) mod.vegtype=Ssortingng(cSsortingng: sqlite3_column_text(stmt, 4)) mod.details=Ssortingng(cSsortingng: 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:Ssortingng = "" var image:Ssortingng = "" var name:Ssortingng = "" var foodtype:Ssortingng = "" var vegtype:Ssortingng = "" var details:Ssortingng = "" var mealtype:Ssortingng = "" var date:Ssortingng = "" } 

Base de données d’access:

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

base de donnée feu feu:

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

J’ai écrit une librairie SQLite3 écrite en Swift .

C’est en fait un wrapper de très haut niveau avec une API très simple, mais de toute façon, il a un code interop de bas niveau C, et je poste ici une partie (simplifiée) pour montrer l’interopérabilité C.

  struct C { static let NULL = COpaquePointer.null() } func open(filename:Ssortingng, flags:OpenFlag) { let name2 = filename.cSsortingngUsingEncoding(NSUTF8SsortingngEncoding)! 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:Ssortingng) -> (statements:[Core.Statement], tail:Ssortingng) { 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 NSSsortingng var zSql = UnsafePointer(sql2.UTF8Ssortingng) var zTail = UnsafePointer.null() var len1 = sql2.lengthOfBytesUsingEncoding(NSUTF8SsortingngEncoding); var maxlen2 = Int32(len1)+1 while let one = once(zSql, maxlen2, &zTail) { stmts.append(one) zSql = zTail } let rest1 = Ssortingng.fromCSsortingng(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) -> Ssortingng { let bc = sqlite3_column_bytes(_rawptr, Int32(index)) let cs = sqlite3_column_text(_rawptr, Int32(index)) let s1 = bc == 0 ? "" : Ssortingng.fromCSsortingng(UnsafePointer(cs))! return s1 } func finalize() { let r = sqlite3_finalize(_rawptr) database.checkNoErrorWith(resultCode: r) _rawptr = C.NULL } 

Si vous voulez un code source complet de ce wrapper de bas niveau, consultez ces fichiers.

Configurez votre projet Swift pour gérer les appels SQLite C:

Créez un fichier d’en-tête de pontage pour le projet. Reportez-vous à la section Importation d’Objective-C dans Swift du chapitre Utilisation de Swift avec Cocoa et Objective-C. Cet en-tête de pontage doit importer sqlite3.h:

Ajoutez le libsqlite3.0.dylib à votre projet. Voir la documentation d’Apple concernant l’ajout de bibliothèque / framework à un projet.

et utilisé le code suivant

  func executeQuery(query: NSSsortingng ) -> Int { if sqlite3_open(databasePath! as Ssortingng, &database) != SQLITE_OK { println("Databse is not open") return 0 } else { query.ssortingngByReplacingOccurrencesOfSsortingng("null", withSsortingng: "") var cStatement:COpaquePointer = nil var executeSql = query as NSSsortingng var lastId : Int? var sqlStatement = executeSql.cSsortingngUsingEncoding(NSUTF8SsortingngEncoding) 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: NSSsortingng, 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 keySsortingng = sqlite3_column_name(cStatement,Int32(i)) thisDict.setObject(result, forKey: Ssortingng.fromCSsortingng(UnsafePointer(keySsortingng))!) } result = NSNull() } if result as! NSObject != NSNull() { var keySsortingng = sqlite3_column_name(cStatement,Int32(i)) thisDict.setObject(result, forKey: Ssortingng.fromCSsortingng(UnsafePointer(keySsortingng))!) } } thisArray.addObject(NSMutableDictionary(dictionary: thisDict)) } sqlite3_finalize(cStatement) } return thisArray } func prepare(sql : NSSsortingng) -> COpaquePointer { var cStatement:COpaquePointer = nil sqlite3_open(databasePath! as Ssortingng, &database) var utfSql = sql.UTF8Ssortingng if sqlite3_prepare(database, utfSql, -1, &cStatement, nil) == 0 { sqlite3_close(database) return cStatement } else { sqlite3_close(database) return nil } } } 

Parfois, une version Swift de l’approche “SQLite en 5 minutes ou moins” affichée sur sqlite.org est suffisante. L’approche «5 minutes ou moins» utilise sqlite3_exec() qui est un wrapper pratique pour sqlite3_prepare() , sqlite3_step() , sqlite3_column() et sqlite3_finalize() .

Swift 2.2 peut directement prendre en charge le pointeur de la fonction de callback sqlite3_exec() tant que func procédure non-instance globale ou fermeture de littéral {} .

typealias lisibles

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

Approche de rappel

 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(Ssortingng(format: "ERROR: Usage: %s DATABASE SQL-STATEMENT", argv[0])) return 1 } rc = sqlite3_open(argv[1], &db) if rc != 0 { print("ERROR: sqlite3_open " + Ssortingng.fromCSsortingng(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 " + Ssortingng.fromCSsortingng(zErrMsg)! ?? "") sqlite3_free(zErrMsg) } sqlite3_close(db) return 0 } 

Approche de fermeture

 func sqlQueryClosureBasic(argc argc: Int, argv: [Ssortingng]) -> Int { var db: sqlite3 = nil var zErrMsg:CCharPointer = nil var rc: Int32 = 0 if argc != 3 { print(Ssortingng(format: "ERROR: Usage: %s DATABASE SQL-STATEMENT", argv[0])) return 1 } rc = sqlite3_open(argv[1], &db) if rc != 0 { print("ERROR: sqlite3_open " + Ssortingng.fromCSsortingng(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 } 

Pour préparer un projet Xcode à appeler une bibliothèque C telle que SQLite, vous devez (1) append un en-tête de fichier Bridging-Header.h comme #import "sqlite3.h" , (2) append Bridging-Header.h à Objective-C Bridging Header dans les parameters du projet et (3) ajout de libsqlite3.tbd aux parameters cible Link Binary With Library .

L' exemple de "SQLite en 5 minutes ou moins" de sqlite.org est implémenté ici dans un projet Swift Xcode7.

Vous pouvez également configurer SQLite avec swift en utilisant la classe à une tonne.

Référer

https://github.com/hasyapanchasara/SQLite_SingleManagerClass

Méthode pour créer une firebase database

 func methodToCreateDatabase() -> NSURL?{} 

Méthode pour insérer, mettre à jour et supprimer des données

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

Méthode pour sélectionner des données

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

Vous pouvez utiliser cette bibliothèque dans Swift for SQLite https://github.com/pmurphyjam/SQLiteDemo

SQLiteDemo

Démo SQLite utilisant Swift avec la classe SQLDataAccess écrite en Swift

Ajout à votre projet

Vous avez seulement besoin de trois fichiers à append à votre projet * SQLDataAccess.swift * DataConstants.swift * Bridging-Header.h Bridging-Header doit être défini dans le projet “Objective-C Bridging Header” de votre Xcode sous “Swift Comstackr – General”

Exemples d’utilisation

Suivez simplement le code dans ViewController.swift pour savoir comment écrire du code SQL simple avec SQLDataAccess.swift. Vous devez d’abord ouvrir la firebase database SQLite avec laquelle vous traitez.

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

Si openConnection a réussi, vous pouvez maintenant insérer un simple insert dans Table 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)") } ``` 

Voyez comme c’était simple!

Le premier terme de db.executeStatement est votre SQL en tant que Ssortingng, tous les termes qui suivent sont une liste d’arguments variadiques de type Any, et sont vos parameters dans un tableau. Tous ces termes sont séparés par des virgules dans votre liste d’arguments SQL. Vous pouvez entrer des chaînes, des nombres entiers, des dates et des bulles juste après la déclaration de suite car tous ces termes sont considérés comme des parameters de la suite. Le tableau d’arguments variadiques facilite simplement la saisie de toutes vos suites en un seul appel executeStatement ou getRecordsForQuery. Si vous ne disposez d’aucun paramètre, n’entrez rien après votre SQL.

Le tableau de résultats est un tableau de dictionnaires où la “clé” est le nom de la colonne de vos tables et où la “valeur” correspond à vos données obtenues à partir de SQLite. Vous pouvez facilement parcourir ce tableau avec une boucle for ou l’imprimer directement ou atsortingbuer ces éléments Dictionary à des classes d’object de données personnalisées que vous utilisez dans vos contrôleurs View pour la consommation de modèle.

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

SQLDataAccess stockera les entiers long, text, double, float, blob, Date, entier et long. Pour les blobs, vous pouvez stocker des fichiers binarys, varbinary, blob.

Pour le texte, vous pouvez stocker le caractère, le caractère, le clob, le caractère national variable, le caractère natif, nchar, nvarchar, varchar, la variante, le caractère variable, le texte.

Pour les dates, vous pouvez stocker la date, l’heure, l’horodatage, la date.

Pour les entiers, vous pouvez stocker bigint, bit, bool, boolean, int2, int8, entier, mediumint, smallint, tinyint, int.

Pour les doubles, vous pouvez stocker des valeurs décimales, double précision, flottant, numérique, réel, double. Le double a la plus grande précision.

Vous pouvez même stocker des Null de type Null.

Dans ViewController.swift, un exemple plus complexe montre comment insérer un dictionnaire en tant que «blob». De plus, SQLDataAccess comprend Swift Date () natif afin que vous puissiez insérer ces objects sans les convertir et les convertir en texte et les stocker, puis les récupérer du texte à la date.

Bien sûr, le véritable pouvoir de SQLite est sa capacité de transaction. Ici, vous pouvez littéralement mettre en queue 400 instructions SQL avec des parameters et les insérer tous en même temps, ce qui est très puissant car il est si rapide. ViewController.swift vous montre également comment faire cela. Tout ce que vous faites est de créer un tableau de dictionnaires appelé «sqlAndParams», dans ce tableau, vos dictionnaires de stockage avec deux clés «SQL» pour l’instruction ou la requête de suite Ssortingng, et «PARAMS» qui est juste un tableau d’objects SQLite. comprend pour cette requête. Chaque «sqlParams», qui est un dictionnaire individuel de parameters de requête suite plus, est ensuite stocké dans le tableau «sqlAndParams». Une fois que vous avez créé ce tableau, vous appelez simplement.

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

De plus, toutes les méthodes executeStatement et getRecordsForQuery peuvent être effectuées avec une simple requête Ssortingng for SQL et un tableau pour les parameters requirejs par la requête.

 ```swift let sql : Ssortingng = "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)") } ``` 

Une version d’Objective-C existe également et s’appelle le même SQLDataAccess. Vous pouvez maintenant choisir d’écrire votre suite dans Objective-C ou Swift. De plus, SQLDataAccess fonctionnera également avec SQLCipher, le code actuel n’est pas encore configuré pour fonctionner avec lui, mais il est assez facile à faire, et la version Objective-C de SQLDataAccess en est un exemple.

SQLDataAccess est une classe très rapide et efficace, et peut être utilisée à la place de CoreData, qui utilise simplement SQLite comme magasin de données sous-jacent, sans tous les incidents de défaillance liés à l’intégrité des données CoreData fournis avec CoreData.