简体   繁体   中英

iOS Firebase sign in. Show activity indicator after Google account choosing

I have a ViewController with a Sign in button used to sign in into Firebase with a Google Account:

GIDSignIn.sharedInstance().signIn()

When I click the button, this appears:

Google account choosing

After selecting an account and if the authentication is successful, I want to load a second ViewController. For this, I have a listener in the first ViewController that will sign in again when the authentication state changes, this time successfully, without asking the account again and sending me directly to the second ViewController:

Auth.auth().addStateDidChangeListener({ auth, user in
    if let _ = user {
        GIDSignIn.sharedInstance().signIn()
    }
})

The problem is that I want an activity indicator to be shown when I go back to the first ViewController from the account chooser. Because the app may be there for a few seconds during the authentication process and I don't want the user to tap again the Sign In button, while the first signing in hasn't already finished.

I need a way to recognise that a signing in process is taking place, to show an activity indicator that locks the screen to prevent the user from tapping again Sign in .

WORKAROUND 1

When I click the Sign in with Google button, I set an UserDefaults integer as 1. Then, when the ViewController is reloaded after the Google account chooser, I look for this integer and if it's 1, I don't stop the activity Indicator.

Because I want the activity indicator shown since the user clicks the button until the authentication is completed .

When button is clicked I do:

GIDSignIn.sharedInstance().signIn()
UserDefaults.standard.set(1, forKey: "signingIn")
UserDefaults.standard.synchronize()

In viewWillAppear I do:

if let _ = user {
    GIDSignIn.sharedInstance().signIn()
} else {
    if UserDefaults.standard.integer(forKey: "signingIn") != 1 {
        self.stopActivityIndicator()
    } else {
        UserDefaults.standard.set(0, forKey: "signingIn")
        UserDefaults.standard.synchronize()
    }
}

When the authentication is completed, in GIDSignInDelegate there is the function that will be called. In this function, the activity indicator must be stopped:

// The sign-in flow has finished and was successful if |error| is |nil|.
- (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user withError:(NSError *)error;

WORKAROUND 2

I do a put the signIn Google function into a completion handler but it doesn't work:

self.completionHandlerSigIn {
    self.stopActivityIndicator()
}

And the function is this:

func completionHandlerSigIn(completion: () -> Void) {
    GIDSignIn.sharedInstance().signIn()
}

The problem is that the view is reloaded during the sign in process, after the account choosing. I need a way to recognize that I come from the Google Account choosing screen.

Just show the loading indicator right when the user clicks sign in, then hide it either when the authentication process returns with error or after processing the result. I don't use google sign in, but I can give you my example with Twitter.

@IBAction func onTwitterClicked(_ sender: UIButton) {
    AuthManager.shared.loginWithTwitter(self) 
}

Here is the loginWithTwitter method in AuthManager:

func loginWithTwitter(_ viewController:BaseController) {
        self.provider = .twitter
        viewController.showLoadingPanel()
        TWTRTwitter.sharedInstance().logIn(completion: {session, error in
            guard (error == nil) else {
                viewController.hideLoadingPanel()
                viewController.showInfoAlert("Oops", error!.localizedDescription, nil)
                return
            }
            let credential = TwitterAuthProvider.credential(withToken: session!.authToken, secret: session!.authTokenSecret)
            self.auth.signIn(with: credential, completion: {user, error in
                viewController.hideLoadingPanel()
                guard error == nil else {
                    viewController.showInfoAlert("Oops", error!.localizedDescription, nil)
                    return
                }
                self.tryConfirmUserInFirestore(user, viewController)
            })
        })
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM