Home > Blockchain >  Navigation after google sign in | UIKit
Navigation after google sign in | UIKit

Time:06-20

I am trying to Navigate to my main content after integration google sign in a separate Login Page. Before creating the login page, my app's entry point was the Navigation controller.. Now I needed users to login before that so I added a View Controller with google sign in button, and the sign in is working fine. this is my storyboard:

My Storyboard

Now I want if the sign in succeed, to display the app's main content view (which is as if the entry point is the Navigation Controller from now on). I tried the following approach:

    @IBAction func signIn(_ sender: Any) {
    let signInConfig = GIDConfiguration.init(clientID: "xyz.apps.googleusercontent.com")
    GIDSignIn.sharedInstance.signIn(with: signInConfig, presenting: self) { user, error in
      guard error == nil else { return }

      // If sign in succeeded, display the app's main content View.
        let vc = self.storyboard?.instantiateViewController(withIdentifier: "scanReceiptsViewController") as! ViewController
        self.navigationController?.pushViewController(vc, animated: true)
        self.present(vc, animated: true, completion: nil)
    }

}

There are 2 problems:

  • the new viewcontroller is presented modally, users can very easily go back to the login page and it distrubs the flow of my app
  • user will need to login everytime to navigate to the main content view controller, I want that if signed in the entry point becomes the main storyboard from now on. if that makes sense

Thank you and sorry I'm new into learning swift!

CodePudding user response:

I would recommend that you keep your navigation controller (I will refer to it from now on as ScanRecipientsViewController) as the default app entry point, since users only need to see the login screen if they are not logged in, which is most of the time not the case. This will give us the benefit of a slightly faster and smoother performance at the app start when the user is logged in.

You could handle this case in your AppDelegate's func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool method. For example, check if the user is logged in, if not, set your LoginController as the new root controller, which will replace your ScanRecipientsViewController that was set as root by the storyboard.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    if GIDSignIn.sharedInstance.currentUser == nil { // just a guess, please refer to the documentation on how to check if the user is logged in
        let storyboard = UIStoryboard(name: "Login", bundle: nil)

        /*
        If you use the SceneDelegate in your project, you will need to retrieve the window object from it instead of from the AppDelegate.

        let window = (UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate)?.window 
        */

        window?.rootViewController = storyboard.instantiateViewController(withIdentifier: "LoginController")
    }

    return true
}

After the user successfully logs in, you can create a new instance of your ScanRecipientsViewController and set it as the root controller back again. You can do this by e.g. creating a public method in your AppDelegate:

extension AppDelegate {
    func openRecipientsController() {
       let storyboard = UIStoryboard(name: "Home", bundle: nil)

       /*
       If you use the SceneDelegate in your project, you will need to retrieve the window object from it instead of from the AppDelegate.

       let window = (UIApplication.shared.connectedScenes.first?.delegate as? SceneDelegate)?.window 
       */

       window?.rootViewController = storyboard.instantiateInitialViewController()
    }
}

and in your LoginViewController:

@IBAction func signIn(_ sender: Any) {
    let signInConfig = GIDConfiguration.init(clientID: "xyz.apps.googleusercontent.com")
    GIDSignIn.sharedInstance.signIn(with: signInConfig, presenting: self) { user, error in
        guard error == nil else { return }

        // If sign in succeeded, display the app's main content View.
        (UIApplication.shared.delegate as? AppDelegate)?.openRecipientsController()
    }

}

As a last thing, you normally don't use both pushing and presenting at the same time, you need to choose one of the two options.

let vc = self.storyboard?.instantiateViewController(withIdentifier: "scanReceiptsViewController") as! ViewController
self.navigationController?.pushViewController(vc, animated: true)
self.present(vc, animated: true, completion: nil)

I wish you lots of fun learning iOS development with Swift!

  • Related