Brian Parkes
Brian Parkes

Reputation: 13

Unable to dismiss a UIAlertController called from a closure

I have a login screen that raises an alert when login fails. The code that calls the alert is run from a callback closure which itself calls a function in the main VC.

        _ = UserProfile.logIn(emailAddressLabel.text!, passwordLabel.text!) { success in
            if success {
                self.performSegue(withIdentifier: "mainTabBarSegue", sender: nil)
            }
            else {
                self.displayFailedLoginAlert()
            }

            self.loggingIn = false
        }

and the displayFailedLoginAlert looks like this:

func displayFailedLoginAlert () {
    let alert = UIAlertController(title: "Login", message: "Login Failed", preferredStyle: UIAlertControllerStyle.alert)
    alert.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.default, handler: { _ in
        alert.dismiss(animated: false, completion: nil)
    }))
    self.present(alert, animated: false, completion: nil)
}

However, when I do this I get:

Warning: Attempt to present <UIAlertController: 0x7ff8fd0b5800>  on <LoginViewController: 0x7ff8fcc0deb0> which is already presenting <UIAlertController: 0x7ff8fe0cca00>

I have tried a number of different approaches and either get this or a crash if I use a UIAlertController as a class member. What am I doing wrong, I just can't see it?

Upvotes: 1

Views: 273

Answers (2)

Brian Parkes
Brian Parkes

Reputation: 13

The issue was that, each time the user logged in I added an observer to the API call. So, on the second login attempt the closure was called twice and so raised the error. Thanks to Frizzo for pointing me in the right direction

Upvotes: 0

Connor Neville
Connor Neville

Reputation: 7361

You don't need to tell the alert to dismiss at all. The default behavior when tapping an action in a UIAlertController is that the alert will dismiss. Just pass nil to the handler.

Upvotes: 1

Related Questions