1

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.

TommyBs
  • 9,354
  • 4
  • 34
  • 65
  • `Authenticator.shared` is not observing on its own. It won't trigger an update. When in the `body` use `authenticator`. Observing is done when wrapped with `@ObservedObject` and `@StateObject` – lorem ipsum Aug 10 '21 at 21:35
  • It's the `.sheet` line that isn't working which is referencing `authenticator` rather than `Authenticator.shared` as mentioned in my post – TommyBs Aug 11 '21 at 07:06
  • How can you observe "the authentication state change", anyway? If the authentication is based on a bearer token, a user gets "signed out" if the access token expires. Since access tokens are opaque data, a client cannot know when this happens - you have to perform a request to the protected resource - which then returns an appropriate HTTP status code. Or do you possibly mean "is registered"? – CouchDeveloper Aug 11 '21 at 09:28
  • I use the firebase auth handler to inform me of user authentication state changes, and then update my authenticator variable accordingly. I've edited to show this – TommyBs Aug 11 '21 at 09:38
  • Thank you, this question and @Jake guided me to the correct solution! – Martin Majewski Sep 17 '21 at 10:57

1 Answers1

1

I believe it's as simple as modifying your sheet code to:

.sheet(isPresented: !$authenticator.isSignedIn) {
    AuthenticationView()
}
Jake
  • 2,126
  • 1
  • 10
  • 23
  • The $ is important. It references the observable object and listens for changes. – Jake Aug 10 '21 at 20:54
  • Actually, there is a little more to it. I'll link to an answer to allow you to add the ! in front of a bound bool to invert the value https://stackoverflow.com/a/61733134/9333764 – Jake Aug 10 '21 at 20:59
  • Thanks for the link, it's late where I am so will try to do a little more reading in the morning from that linked answer – TommyBs Aug 10 '21 at 21:10