I'm getting stuck into swiftui and trying to show a sheet based on a property in an external class. I want the view to updated based on this property. From what I understand I need to use an ObservableObject with a @Published property. However I can't seem to get my View to "observe" the property in question. I've tried using @ObservedObject, @State and @EnvironmentObject. But it all results in an error as follows:
Cannot convert value of type 'Bool' to expected argument type 'Binding<Bool>'
This errors on the .sheet
line below in the view class
My external class looks like so:
class Authenticator: ObservableObject {
@Published var isSignedIn: Bool = false
static let shared = Authenticator()
init() {
handle = Auth.auth().addStateDidChangeListener({[weak self] auth, user in
if user != nil {
self?.isSignedIn = true
} else {
self?.isSignedIn = false
}
})
}
func signIn(email:String, password:String) {
//signin
isSignedIn = true;
}
}
//View Code
struct AccountView: View {
@ObservedObject var authenticator:Authenticator = Authenticator.shared
var body: some View {
NavigationView {
ZStack {
Color.white.edgesIgnoringSafeArea(.all).frame(maxWidth:.infinity, maxHeight: .infinity)
if Authenticator.shared.isSignedIn {
Button {
//sign out here which then updates isSignedIn property
Authenticator.shared.signout()
} label: {
Text("Sign out")
}
}
}.sheet(isPresented: !authenticator.isSignedIn) {
} content: {
AuthenticationView()
}
}
}
}
I'm not sure if the issue is arising because my ObservableObject is a singleton? My Code will sign in, and then if I relaunch the app the signed in state is observed. It just doesn't seem to update my UI at the time.
My Authenticator is a singleton as I'm using Firebase Auth and trying to observe the authentication state change. But I don't know if this is the wrong approach and whether I should instantiate an instance of my authenticator in my App
instead and pass that in as an @EnvironmentObject
.
Any help would be appreciated.