Why is the iOS 11: self.performSegue() not working?

Viewed 1311

I started the migration to Xcode 9 & iOS 11 build today.

In my storybased app, the following code:

self.performSegue(withIdentifier: Const.UI.Segue.showIntro, sender: self)

runs fine in all previous iOS (just verified with iOS 10.3, 10.0, 9.0) but does not run in iOS 11.

Additional code:

private func handleSuccessfulLogin() {
    self.log.info("Logged In")
    DispatchQueue.main.async(){
        self.performSegue(withIdentifier: Const.UI.Segue.showIntro, sender: self)
    }
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    print("starting segue " + segue.identifier!)
}

override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
    print("should perform segue")
    return true
}

printout (iOS 11):

> Logged In
> starting segue showIntroSegue

Expected result: new controller pushed

Actual result iOS 11: nothing at all happens

Any ideas what the reason might be?

The function handleSuccessfulLogin() is called after a successful login with AWSCognito / AWSFacebookSignInProvider, a facebook login. On iOS there is a new popup continue with facebook which I suspect to be the reason, but I got no way to verify it.. On the 2nd call this popup does not appear (as facebook already is authorized), and then the segue triggers correctly.

Note, I also tried this snippet, same result.

OperationQueue.main.addOperation {
        [weak self] in
        self?.performSegue(withIdentifier: Const.UI.Segue.showIntro, sender: self)
    }
2 Answers

I found the solution to be at a completely different place (as so often). The reason was that I had a logic in place in applicationDidBecomeActive that was replacing the current storyboard (bad approach!) - the additional popup from the FB Kit led to a recreation of my container view controller. Thus i had self.navigationController == nil during the call to perform the segue.

According to discussions, viewDidLoad is inappropriate to place to call perform segue, but there are plenty of user cases where wanting to trigger a segue before the view appears, special case as it has been working previous to X9, as the segue seem to trigger when either having the view controller in a navigation controller or dispatching to main (in viewDidLoad), which should be already on the main thread when presenting a loaded view.

This I would consider a bug, rather than an undocumented feature.

Related