如何在 Swift 中全局声明数据库连接变量

How to declare database connection variable globally in Swift

我需要初始化一个变量以连接到 Swift 中的 SQLite 数据库。我正在使用 SQLite.swift 库,需要使用此行连接到数据库:

let db = try Connection("path/to/db.sqlite3")

但是,这一行本身是行不通的,因为它需要用 try/catch 块包围。 Try/catch 块除非在方法或函数中定义,否则将不起作用,所以现在我们有

public func connectToDB() {
    do {
        let path = NSSearchPathForDirectoriesInDomains(
            .DocumentDirectory, .UserDomainMask, true
            ).first!
        let db = try Connection("\(path)/db.sqlite3")
    }
    catch {
        print("error connecting to database")
    }
}

但是,这不允许我从同一文件中的其他方法访问变量,而这正是我需要做的。全局 let 声明也需要初始化,这意味着它不能全局设置。如何从 class?

中的其他方法访问此对象

你可以这样做:

let db = try! Connection("path/to/db.sqlite3")
// db is a Connection but the app dies if there was an error.

或者您可以这样做:

let db = try? Connection("path/to/db.sqlite3")
// db is an Optional<Connection> and nil if there was an error.

或者您可以这样做:

let db = { () -> Connection in
    do {
        return try Connection("path/to/db.sqlite3")
    } catch {
        do {
            return try Connection() // transient in-memory database
        } catch {
            fatalError()
        }
    }
}() // invoke this closure immediately

您可以在闭包中做任何您喜欢的事情来处理错误情况。

我不确定为什么上面的答案是正确的 - 从最初的问题看来他有 2 个问题,一个是使用 Try/Catch,另一个是变量范围。

如果你在函数内部初始化一个变量,我的理解是它会随着函数一起消失。我在我的代码中这样做如下:

var db: FMDatabase?

func openDB() -> FMDatabase {
    do {
        let path = NSSearchPathForDirectoriesInDomains(
            .DocumentDirectory, .UserDomainMask, true
            ).first!
        let db = try Connection("\(path)/db.sqlite3")
        return db
    }
    catch {
        print("error connecting to database")
        return nil
    }

}

现在您可以将 "db" 作为 class 变量访问。希望对您有所帮助。

如果使用包装器 SQLite.swift,代码可能如下所示:

var db: Connection?

func openDB() -> Connection {
    //Simply return if the connection already exists
    if db == nil {
        do { let path = NSSearchPathForDirectoriesInDomains(
            .documentDirectory, .userDomainMask, true
            ).first!
            db = try Connection("\(path)/database.sqlite3")
            print("Database opened")
            print(path)
        }
        catch {
            print("error connecting to database \(error)")
            print("In func openDB() -> Connection")
        }
    }
    return db!
}