Ich suche nach einer Möglichkeit, mit Swift-Code auf eine SQLite-Datenbank in meiner App zuzugreifen.
Ich weiß, dass ich in Objective C einen SQLite Wrapper und den Bridging-Header verwenden kann, aber ich würde dieses Projekt lieber vollständig in Swift ausführen können. Gibt es eine Möglichkeit, dies zu tun? Wenn ja, kann mich jemand auf eine Referenz verweisen, die zeigt, wie eine Abfrage gesendet, Zeilen abgerufen usw. wird?
let dbPath = try! FileManager.default.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("test.sqlite").path
.Antworten:
Während Sie wahrscheinlich einen der vielen SQLite-Wrapper verwenden sollten, würden Sie Folgendes tun, wenn Sie wissen möchten, wie Sie die SQLite-Bibliothek selbst aufrufen können:
Konfigurieren Sie Ihr Swift-Projekt für die Verarbeitung von SQLite C-Aufrufen. Wenn Sie Xcode 9 oder höher verwenden, können Sie einfach Folgendes tun:
Datenbank erstellen / öffnen.
Hinweis: Ich weiß, dass es seltsam erscheint, die Datenbank zu schließen, wenn sie nicht geöffnet werden kann. In der
sqlite3_open
Dokumentation wird jedoch ausdrücklich darauf hingewiesen, dass dies erforderlich ist, um Speicherverluste zu vermeiden:Verwenden Sie
sqlite3_exec
diese Option , um SQL auszuführen (z. B. Tabelle erstellen).Verwenden Sie
sqlite3_prepare_v2
diese Option , um SQL mit einem?
Platzhalter vorzubereiten, an den der Wert gebunden wird.Beachten Sie, dass die
SQLITE_TRANSIENT
Konstante verwendet wird, die wie folgt implementiert werden kann:Setzen Sie SQL zurück, um einen anderen Wert einzufügen. In diesem Beispiel füge ich einen
NULL
Wert ein:Finalisieren Sie die vorbereitete Anweisung, um den mit dieser vorbereiteten Anweisung verknüpften Speicher wiederherzustellen:
Bereiten Sie eine neue Anweisung zum Auswählen von Werten aus Tabelle und Schleife vor, indem Sie die Werte abrufen:
Datenbank schließen:
Informationen zu Swift 2 und älteren Versionen von Xcode finden Sie in früheren Versionen dieser Antwort .
quelle
guard
stattdessen Anweisungen verwenden.Das Beste, was Sie tun können, ist, die dynamische Bibliothek in einen Bridging-Header zu importieren:
#import <sqlite3.h>
sie oben hinzuSie können dann wie
sqlite3_open
in Ihrem schnellen Code auf alle c-Methoden zugreifen .Möglicherweise möchten Sie jedoch nur verwenden FMDB verwenden und diese über den Bridging-Header importieren, da dies ein objektorientierterer Wrapper von SQLite ist. Der Umgang mit C-Zeigern und -Strukturen ist in Swift umständlich.
quelle
NSDateFormatter
. Meine Absicht war es jedoch weniger, diesen speziellen Aspekt dieser speziellen Implementierungen zu kritisieren, als darauf hinzuweisen, dass dies auf ein breiteres Problem hinweist und dass diese nicht die jahrelange Verfeinerung aufweisen, die Lösungen wie FMDB haben. Ich denke, die Leute sind zu schnell, um bewährte Objective-C-Lösungen zugunsten weniger ausgereifter Swift-Implementierungen zu verwerfen (TFHpple vs NDHpple sind ein weiteres gutes Beispiel).Auch ich suchte nach einer Möglichkeit, mit SQLite so zu interagieren, wie ich es zuvor in Objective-C gewohnt war. Zugegeben, aus Gründen der C-Kompatibilität habe ich nur die reine C-API verwendet.
Da derzeit kein Wrapper für SQLite in Swift vorhanden ist und der oben erwähnte SQLiteDB-Code eine etwas höhere Ebene hat und eine bestimmte Verwendung voraussetzt, habe ich beschlossen, einen Wrapper zu erstellen und mich dabei ein wenig mit Swift vertraut zu machen. Sie finden es hier: https://github.com/chrismsimpson/SwiftSQLite .
quelle
Ich habe eine elegante SQLite-Bibliothek namens SwiftData erstellt, die vollständig in Swift geschrieben wurde .
Einige seiner Funktionen sind:
Es bietet eine einfache Möglichkeit, 'Änderungen' auszuführen (z. B. EINFÜGEN, AKTUALISIEREN, LÖSCHEN usw.):
und 'Abfragen' (zB SELECT):
Zusammen mit vielen weiteren Funktionen!
Sie können es hier überprüfen
quelle
Noch ein SQLite-Wrapper für Swift 2 und Swift 3: http://github.com/groue/GRDB.swift
Eigenschaften:
Eine API, die Benutzern von ccgus / fmdb bekannt vorkommt
Eine SQLite-API auf niedriger Ebene, die die Swift-Standardbibliothek nutzt
Eine hübsche Swift-Abfrageoberfläche für SQL-allergische Entwickler
Unterstützung für den SQLite WAL-Modus und gleichzeitiger Datenbankzugriff für zusätzliche Leistung
Eine Record-Klasse, die Ergebnismengen umschließt, Ihre benutzerdefinierten SQL-Abfragen zum Frühstück verarbeitet und grundlegende CRUD-Operationen bereitstellt
Schnelle Schriftfreiheit: Wählen Sie den richtigen schnellen Typ, der zu Ihren Daten passt. Verwenden Sie bei Bedarf Int64 oder bleiben Sie beim praktischen Int. Speichern und lesen Sie NSDate oder NSDateComponents. Deklarieren Sie Swift-Aufzählungen für diskrete Datentypen. Definieren Sie Ihre eigenen datenbankkonvertierbaren Typen.
Datenbankmigrationen
Geschwindigkeit: https://github.com/groue/GRDB.swift/wiki/Performance
quelle
AppDelegate.swift
Database.swift
Model.swift
Zugriff auf Datenbank:
Datenbank Abfrage Feuer:
quelle
Dies ist bei weitem die beste SQLite-Bibliothek, die ich in Swift verwendet habe: https://github.com/stephencelis/SQLite.swift
Schauen Sie sich die Codebeispiele an. So viel sauberer als die C-API:
In der Dokumentation heißt es außerdem, dass "SQLite.swift auch als leichter, Swift-freundlicher Wrapper über die C-API funktioniert", und es folgen einige Beispiele dafür.
quelle
Ich habe eine in Swift geschriebene SQLite3-Wrapper-Bibliothek geschrieben .
Dies ist eigentlich ein Wrapper auf sehr hoher Ebene mit einer sehr einfachen API, aber trotzdem hat er C-Interop-Code auf niedriger Ebene, und ich poste hier einen (vereinfachten) Teil davon, um die C-Interop zu zeigen.
Wenn Sie einen vollständigen Quellcode für diesen Low-Level-Wrapper benötigen, lesen Sie diese Dateien.
quelle
Konfigurieren Sie Ihr Swift-Projekt für die Verarbeitung von SQLite C-Aufrufen:
und folgenden Code verwendet
quelle
Manchmal ist eine Swift-Version des auf sqlite.org gezeigten Ansatzes "SQLite in 5 Minuten oder weniger" ausreichend. Die „5 Minuten oder weniger“ Ansatz verwendet , die ein Convenience - Wrapper ist für , , , und
sqlite3_exec()
sqlite3_prepare()
sqlite3_step()
sqlite3_column()
sqlite3_finalize()
.Swift 2.2 kann den
sqlite3_exec()
callback
Funktionszeiger direkt als globale Prozedur ohne Instanzfunc
oder als nicht erfassenden Literalabschluss unterstützen{}
.Lesbar
typealias
Rückrufansatz
Abschlussansatz
Um ein Xcode-Projekt für den Aufruf einer C-Bibliothek wie SQLite vorzubereiten, müssen Sie (1) eine Bridging-Header.h-Dateireferenz C-Header
#import "sqlite3.h"
hinzufügen, wie (2) Bridging-Header.h zu Objective-C Bridging Header im Projekt hinzufügen Einstellungen und (3)libsqlite3.tbd
zu Link Binary With Library hinzufügen verknüpfen" .Das sqlite.org ‚s ‚SQLite in 5 Minuten oder weniger‘ Beispiel ist in einem Swift Xcode7 Projekt umgesetzt hier .
quelle
Sie können SQLite auch schnell und einfach mit einer einzelnen Tonne konfigurieren.
Verweisen
https://github.com/hasyapanchasara/SQLite_SingleManagerClass
Methode zum Erstellen einer Datenbank
Methode zum Einfügen, Aktualisieren und Löschen von Daten
Methode zur Auswahl von Daten
quelle
Sie können diese Bibliothek in Swift für SQLite https://github.com/pmurphyjam/SQLiteDemo verwenden
SQLiteDemo
SQLite-Demo mit Swift mit in Swift geschriebener SQLDataAccess-Klasse
Hinzufügen zu Ihrem Projekt
Sie müssen Ihrem Projekt nur drei Dateien hinzufügen. * SQLDataAccess.swift * DataConstants.swift * Bridging-Header.h Der Bridging-Header muss im Xcode-Projekt 'Objective-C Bridging Header' unter 'Swift Compiler - General' festgelegt werden.
Anwendungsbeispiele
Folgen Sie einfach dem Code in ViewController.swift, um zu sehen, wie Sie einfaches SQL mit SQLDataAccess.swift schreiben. Zuerst müssen Sie die SQLite-Datenbank öffnen, mit der Sie sich befassen
Wenn openConnection erfolgreich war, können Sie jetzt eine einfache Einfügung in Table AppInfo vornehmen
Sehen Sie, wie einfach das war!
Der erste Begriff in db.executeStatement ist Ihre SQL als Zeichenfolge. Alle folgenden Begriffe sind eine Liste mit variablen Argumenten vom Typ Any und Ihre Parameter in einem Array. Alle diese Begriffe werden in Ihrer Liste der SQL-Argumente durch Kommas getrennt. Sie können direkt nach der Sequel-Anweisung Strings, Integers, Date's und Blobs eingeben, da alle diese Begriffe als Parameter für die Fortsetzung gelten. Das Array mit variablen Argumenten macht es einfach bequem, Ihre gesamte Fortsetzung in nur einem Aufruf von executeStatement oder getRecordsForQuery einzugeben. Wenn Sie keine Parameter haben, geben Sie nach Ihrem SQL nichts ein.
Das Ergebnisarray ist ein Array von Wörterbüchern, bei dem der 'Schlüssel' der Name Ihrer Tabellenspalte und der 'Wert' Ihre von SQLite erhaltenen Daten sind. Sie können dieses Array einfach mit einer for-Schleife durchlaufen oder direkt ausdrucken oder diese Dictionary-Elemente benutzerdefinierten Datenobjektklassen zuweisen, die Sie in Ihren View Controllern für den Modellverbrauch verwenden.
SQLDataAccess speichert Text, Double, Float, Blob, Datum, Ganzzahl und lange lange Ganzzahlen. Für Blobs können Sie Binär, Varbinär, Blob speichern.
Für Text können Sie Zeichen, Zeichen, Clob, national variierendes Zeichen, natives Zeichen, nchar, nvarchar, varchar, Variante, variierendes Zeichen, Text speichern.
Für Daten können Sie Datum, Uhrzeit, Zeitstempel und Datum speichern.
Für Ganzzahlen können Sie bigint, bit, bool, boolean, int2, int8, Ganzzahl, mediumint, smallint, tinyint, int speichern.
Für Doubles können Sie Dezimalzahlen, doppelte Genauigkeit, Gleitkommazahlen, numerische Werte, reelle Zahlen und doppelte Werte speichern. Double hat die höchste Präzision.
Sie können sogar Nullen vom Typ Null speichern.
In ViewController.swift wird ein komplexeres Beispiel gezeigt, wie ein Wörterbuch als 'Blob' eingefügt wird. Darüber hinaus versteht SQLDataAccess das native Swift Date (), sodass Sie diese Objekte ohne Konvertierung einfügen können. Es konvertiert sie in Text und speichert sie. Wenn sie abgerufen werden, konvertieren Sie sie zurück von Text in Datum.
Die wahre Stärke von SQLite liegt natürlich in der Transaktionsfähigkeit. Hier können Sie buchstäblich 400 SQL-Anweisungen mit Parametern in die Warteschlange stellen und alle auf einmal einfügen, was sehr leistungsfähig ist, da es so schnell ist. ViewController.swift zeigt Ihnen auch ein Beispiel dafür. Alles, was Sie wirklich tun, ist, ein Array von Wörterbüchern mit dem Namen 'sqlAndParams' zu erstellen. In diesem Array speichern Sie Wörterbücher mit zwei Schlüsseln 'SQL' für die String-Folge-Anweisung oder -Abfrage und 'PARAMS', das nur ein Array nativer Objekte SQLite ist versteht für diese Abfrage. Jedes 'sqlParams', das ein individuelles Wörterbuch der Folgeabfrage plus Parameter ist, wird dann im 'sqlAndParams'-Array gespeichert. Sobald Sie dieses Array erstellt haben, rufen Sie einfach an.
Darüber hinaus können alle Methoden executeStatement und getRecordsForQuery mit einem einfachen String für SQL-Abfragen und einem Array für die von der Abfrage benötigten Parameter ausgeführt werden.
Es gibt auch eine Objective-C-Version, die als SQLDataAccess bezeichnet wird. Jetzt können Sie wählen, ob Sie Ihre Fortsetzung in Objective-C oder Swift schreiben möchten. Darüber hinaus funktioniert SQLDataAccess auch mit SQLCipher. Der vorliegende Code ist noch nicht eingerichtet, um damit zu arbeiten. Dies ist jedoch recht einfach. Ein Beispiel dafür finden Sie in der Objective-C-Version von SQLDataAccess.
SQLDataAccess ist eine sehr schnelle und effiziente Klasse und kann anstelle von CoreData verwendet werden, das wirklich nur SQLite als zugrunde liegenden Datenspeicher verwendet, ohne dass alle mit CoreData verbundenen CoreData-Kerndatenintegritätsfehler abstürzen.
quelle