mercredi 24 novembre 2021

Creating a global SQLite DB Connection with Singleton pattern in Swift

I detect whether a connection exists on a Singleton instance and if it doesn't it will open up a new connection on app start up. However, ideally I'd like for the open function to fire when the Singleton is first created without having to explicitly call it and assign it to some variable within the class.

The way I have the code now it defeats the purpose of having a shared Singleton because I just access the static connection object. When I attempt to change the static conn to an instance variable I get the error Instance member 'conn' cannot be used on type 'DBConnection'

Non-working code

class DBConnection {
    static let shared = DBConnection()
    var conn: Connection? = nil
    
    private init() { }
    
    static func open(dbPath: URL) throws {
        var dbConnections: [Connection] = []
        
        do {
            let dbConnection = try Connection("\(dbPath)/db.sqlite3")
            dbConnections.append(dbConnection)
            print("found connection, \(dbConnections)")
        } catch {
            throw SQLiteDBError.couldNotOpenConnection
        }
        
        self.conn = dbConnections[0]
        print("successfully opened connection")
    }
}

How can you call a private function within a Singleton class on init and assign it to some variable?

Current working code

class DBConnection {
    static let shared = DBConnection()
    static var conn: Connection?
    
    private init() { }
    
    static func open(dbPath: URL) throws {
        var dbConnections: [Connection] = []
        
        do {
            let dbConnection = try Connection("\(dbPath)/db.sqlite3")
            dbConnections.append(dbConnection)
            print("found connection, \(dbConnections)")
        } catch {
            throw SQLiteDBError.couldNotOpenConnection
        }
        
        self.conn = dbConnections[0]
        print("successfully opened connection")
    }
}

Main app init

@main
struct MyApp: App {
    
    init() {
        if DBConnection.conn != nil {
            do {
                try DBConnection.open(dbPath: FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: FileManager.SearchPathDomainMask.userDomainMask)[0])
            } catch {
                print("error")
            }
        } else {
            print("Connection already existed")
        }
    }
    ....
}

Aucun commentaire:

Enregistrer un commentaire