0

I have created an ObservableObject object class, and I need to create 2 inits one with passing a string parameter and another without passing.

class DictionaryModel: ObservableObject {
    @Published var dbName: String = ""
    private var dbQueue: DatabaseQueue!
    var localDBFile: String

//this `init` works fine:

init(_ localDBName: String) {
        self.localDBFile = localDBName
        var config = Configuration()
        config.readonly = false
        guard let dbPath = Bundle.main.path(forResource: localDBName, ofType: "sqlite") else { return }
        do {
            self.dbQueue = try DatabaseQueue(path: dbPath, configuration: config)
        } catch let error {
            print(error.localizedDescription)
        }
    }

}

for the second init I need to change @Published var dbName on different occasions, for example when user choose another database. I need this changing dbName to affects on all views like bookmark, searching and etc..

init() {
    var config = Configuration()
    config.readonly = false
    let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    let dbPath = documentDirectoryURL.appendingPathComponent("\(dbName).sqlite").path
    
    do {
        self.dbQueue = try DatabaseQueue(path: dbPath, configuration: config)
    } catch let error {
        print(error.localizedDescription)
    }
    fetchBookmarks()
}

I keep getting this error self' used in property access 'dbName' before all stored properties are initialized. Is there any way to have two inits in one class one with passing parameter and another without any?

malhal
  • 26,330
  • 7
  • 115
  • 133
Mc.Lover
  • 4,813
  • 9
  • 46
  • 80
  • In the second initializer, where do you intend the value of `dbName` to come from? – Alexander Mar 03 '23 at 17:57
  • @Alexander I am trying to change it with button or something similar – Mc.Lover Mar 03 '23 at 20:32
  • An initialiser needs to set _initial_ values. Without that, how would the `DictionaryModel` behave before you've given it any `dbName` values from the UI? It needs to do _something_. More than likely, what you want is for your UI layer to hold onto a `DictionaryModel?`, and only initialize it with a value once the user has given you a DB name. Then, if the user wants to disconnect (you nil out that variable) and connect to another DB name, you create a new `DictionaryModel` object at that time, and replace the previous one. – Alexander Mar 03 '23 at 20:48

1 Answers1

1

Is there any way to have two inits in one class one with passing parameter and another without any?

Absolutely. But you cannot violate the rules: you cannot, as the error message tells you, "access dbName before all stored properties are initialized." And what stored properties are there? localDBFile. You must set localDBFile to something — and you are not doing that. Even if you just set it to an empty string, you must set it to something.

Moreover, your declaration private var dbQueue: DatabaseQueue! is a really bad idea. Exclamation mark means "crash me". This is an accident waiting to happen.

matt
  • 515,959
  • 87
  • 875
  • 1,141