我正在寻找一种使用Swift代码在我的应用程序中访问SQLite数据库的方法。
我知道我可以在Objective C中使用SQLite包装器并使用桥接头,但是我希望能够完全在Swift中完成此项目。如果可以的话,有没有办法做到这一点,有人可以将我指向一个引用,该引用显示了如何提交查询,检索行等。
虽然您可能应该使用许多SQLite包装器之一,但如果您想知道如何自己调用SQLite库,则可以:
配置您的Swift项目以处理SQLite C调用。如果使用Xcode 9或更高版本,则只需执行以下操作:
import SQLite3
创建/打开数据库。
let fileURL = try! FileManager.default .url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true) .appendingPathComponent("test.sqlite") // open database var db: OpaquePointer? guard sqlite3_open(fileURL.path, &db) == SQLITE_OK else { print("error opening database") sqlite3_close(db) db = nil return }
注意,我知道在打开失败后关闭数据库似乎很奇怪,但是sqlite3_open 文档明确指出我们必须这样做以避免内存泄漏:
sqlite3_open
无论错误是否在打开时发生,与数据库连接句柄关联的资源都应通过将其传递给sqlite3_close()不再需要时释放。
sqlite3_close()
sqlite3_exec
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)") }
sqlite3_prepare_v2
?
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常量:
SQLITE_TRANSIENT
internal let SQLITE_STATIC = unsafeBitCast(0, to: sqlite3_destructor_type.self) internal let SQLITE_TRANSIENT = unsafeBitCast(-1, to: sqlite3_destructor_type.self)
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)") }
if sqlite3_finalize(statement) != SQLITE_OK { let errmsg = String(cString: sqlite3_errmsg(db)!) print("error finalizing prepared statement: \(errmsg)") } statement = nil
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
if sqlite3_close(db) != SQLITE_OK { print("error closing database") } db = nil