简体   繁体   中英

Swift - Call segue inside of a closure

I am trying to call a segue inside of a closure and I can't seem to make it work. The problem is that I don't know how to make the "performSegueWithIdentifier" call since I cannot use the keyword "self" here.

This is being done outside of UIViewController, so I don't know how to call a "performSegueWithIdentifier" without using the keyword "self".

So I would need to create the object where the method is called, but how and which object? Is it the view controller? On the storyboard? or where is it?

func signUp (username: String, password: String) {
    Alamofire.request(.POST, "https://test.xyz.de/api/v1/public/user", parameters:["username" : username, "password": password], encoding: .JSON)
        .responseJSON({ (_, _, JSON, error) -> Void in
            println("Response: \(JSON)")
            if error == nil {
                self.performSegueWithIdentifier("segueToNextScreen", sender: self) // Problem!!
            } else {
                println(error)
            }
        })
}

Thanks in advance and let me know if you need further explanation.

Cheers, Tiago

func signUp (username: String, password: String) {

Alamofire.request(.POST, "https://test.xyz.de/api/v1/public/user", parameters:["username" : username, "password": password], encoding: .JSON)
    .responseJSON({ (_, _, JSON, error) -> Void in
        println("Response: \(JSON)")

        if error == nil {

            dispatch_async(dispatch_get_main_queue()){
                self.performSegueWithIdentifier("segueToNextScreen", sender:self)
                }
        } 
        else {

            println(error)
        }
    })
}

Encapsulating "performSegueWithIndentifier" inside "dispatch_async" worked for me.

You could write a function which you will call inside the block which will perform the seuge. That way you can use the self keyword:

func performSegue(identifier:String){
  self.performSegueWithIdentifier(identifier, sender: self)
}

func signUp (username: String, password: String) {
    Alamofire.request(.POST, "https://test.xyz.de/api/v1/public/user", parameters:["username" : username, "password": password], encoding: .JSON)
        .responseJSON({ (_, _, JSON, error) -> Void in
            println("Response: \(JSON)")
            if error == nil {
                self.performSegue("segueToNextScreen") // Problem!!
            } else {
                println(error)
            }
        })
}

If this is being called from outside a view controller, the question becomes how is it being invoked? The most appropriate solution is probably to add a parameter that takes the view controller it's being invoked from, since any segue can only happen relative to that view controller.

func signup(username:String, password:String, presentingViewController:UIViewController) {
    ...
        presentingViewController.performSegue("segueToNextScreen")
    ...
}

A better approach might be to actually pass in a success block, and then the caller could handle success by performing the appropriate segue. That way your not dependent on any possible caller having a segueToNextScreen method and your separating network interface functionality from user interface functionality, always a good idea since they're really very distinct creatures.

func signup(username:String, password:String, success:()->()) {
    ...
        success()
    ...
}

// in calling ViewController
    signup(username, password) {
        self.performSegue("segueToNextScreen")
    }

Of course, the most obvious solution may be to just put this code into your UIViewController subclass.

Just call self before performSegue and you can call self again inside the method

SWIFT 5

self.performSegue(withIdentifier: "resultViewController", sender: self)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM