iosswiftauthenticationviewcontrollertwitterkit

Swift - Why should I use viewDidAppear rather than viewWillAppear when redirect user if the user logged in already


I'm making twitter client app, using TwitterKit.

The initial VC is loginVC with login button. After login, it presents tableviewVC that shows list of tweets.

I want to redirect the user to tableviewVC directly if the user logged in already before and the session remains.

So I implemented codes in viewWillAppear that check logged-in users and present tableviewVC, but the tableviewVC never presented though the user session remains.

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if TWTRTwitter.sharedInstance().sessionStore.hasLoggedInUsers() {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let tweetVC = storyboard.instantiateViewController(withIdentifier: "TweetTableViewController")
        present(tweetVC, animated: true, completion: nil)
    }
}

But when I implemented the same codes in viewDidAppear, the tableviewVC showed up when the user session remains.

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    if TWTRTwitter.sharedInstance().sessionStore.hasLoggedInUsers() {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let tweetVC = storyboard.instantiateViewController(withIdentifier: "TweetTableViewController")
        present(tweetVC, animated: true, completion: nil)
    }
}

I don't understand why it doesn't work when the codes are in viewWillAppear.

Could someone please explain it for me?


Solution

  • As the methods name explains,

    viewWillApper means the view of the current viewController is going to be appear, still not on the window. So, in that case you cann't present the any viewController over the viewController which is not being displayed in the window.

    viewDidApper means the view of the current viewController is being displayed on the window, That's why you're able to present the new viewController.

    PS: As you want to achieve, in case of already logged in show the listVC. I would suggest to setup the rootViewController of the window in didFinishLaunchingWithOptions method of AppDelegate.

    Like:

        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    
        var rootVC: UIViewController?
        if <check weather user is already logged in> {
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            rootVC = storyboard.instantiateViewController(withIdentifier: "TweetTableViewController")
        }
        else {
            rootVC = <you loginVC object>
        }
    
        self.window?.rootViewController = rootVC
        self.window?.makeKeyAndVisible()
    
    
        return true
    }