Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift - dismissing view controller from within a completion block

Simple question. If I'm within a completion block - for example facebook login using firebase ... and the login has succeeded. If I want to dismiss the current view controller (login viewcontroller) from within the completion block , do I need to get back to main queue to do this. I'm assuming the login completion block is being done on a background thread and any change to UI (ie dismissing the current view controller) should be done on the main thread ... what's best practice here ... or am I missing something?

@IBAction func facebookLoginTapped(sender: AnyObject) {

    //
    let ref = Firebase(url: "https://XXXX.firebaseio.com")
    let facebookLogin = FBSDKLoginManager()
    facebookLogin.logInWithReadPermissions(["email"], fromViewController: self, handler: { (facebookResult, facebookError) -> Void in
        if facebookError != nil {
            print("Facebook login failed. Error \(facebookError)")
        } else if facebookResult.isCancelled {
            print("Facebook login was cancelled.")
        } else {
            //successfully logged in
            //get facbook access token
            let accessToken = FBSDKAccessToken.currentAccessToken().tokenString
            //use access token to authenticate with firebase
            ref.authWithOAuthProvider("facebook", token: accessToken,
                withCompletionBlock: { error, authData in
                    if error != nil {
                        print("Login failed. \(error)")
                    } else {
                        //authData contains
                        print("Logged in! \(authData)")

                        //pop loginvc back to uservc - DO I NEED TO GET MAIN THREAD HERE BEFORE DISMISSING VIEW CONTROLLER
                        self.dismissViewControllerAnimated(true, completion: nil)
                    }
            })
        }
    })
}
like image 337
lozflan Avatar asked Mar 20 '16 22:03

lozflan


People also ask

How do you dismiss the presenting view controller?

When it comes time to dismiss a presented view controller, the preferred approach is to let the presenting view controller dismiss it. In other words, whenever possible, the same view controller that presented the view controller should also take responsibility for dismissing it.


1 Answers

you should "pop" back to the main thread to do this. Its pretty simple, just wrap

self.dismissViewControllerAnimated(true, completion: nil) like this...

Swift 2.x

dispatch_async(dispatch_get_main_queue()){
    self.dismissViewControllerAnimated(true, completion: nil)
}

Swift 3 4 & 5:

DispatchQueue.main.async {
      self.dismiss(animated: true, completion: nil)
}
like image 180
MikeG Avatar answered May 20 '23 04:05

MikeG