Swift UIKit / presenting UIAlert blocks pushing VC

47 views Asked by At

I got simple UIViewController + UIAlert extension:

extension UIViewController {
    func alert(title: String = "", message: String){
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: Localized.ok(), style: .default, handler: nil))
        present(alert, animated: true, completion: nil)
    }
}

Within the ViewController I got a method:

    func findUser() {
        userService.findUser { (userinfo, error) in
            if error != nil {
                if let errText = error?.localizedDescription {
                    self.alert(message: errText)
                }
                self.doAuth()
                return
            }
        }
    }

this doAuth() method should redirect to loginViewController using: navigationController?.pushViewController(loginViewController, animated: false)

The problem is, that in this scenario, this push doesn't work (nothing appears) (I click OK button on the alert, alert dissapears but loginViewController is not pushed)

I refactored extension a little bit:

extension UIViewController {
    func alert(title: String = "", message: String, action completion: (() -> Void)? = nil){
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: Localized.ok(), style: .default, handler: { _ in
                completion?()
        }))

        present(alert, animated: true, completion: nil)
    }
}

so findUser() method is calling doAuth() in differently:

    func findUser() {
        userService.findUser { (userinfo, error) in
            if error != nil {
                if let errText = error?.localizedDescription {
                    self.alert(message: errText){ [weak self] in
                        self?.doAuth()
                    }
                }
                return
            }
        }
    }

and it works! Problem is I have no idea why. And what could have happened in the first scenario? I feel it should be some simple explanation, but I can't figure it out.

Edit

The explanation is simple and was printed in the console:

pushViewController:animated: called on <UINavigationController 0x7f86050b4400> 
while an existing transition or presentation is occurring; the navigation stack 
will not be updated.

So doAuth() (with pushing VC method) was called while alert was visible/presented, so alert took the focus and VC couldn't be pushed.

cc: @Paulw11 @ cookednick

0

There are 0 answers