-1

I am developing a MacOS app that has a login page. When the user pressed the login button i need to send a post request and if the response is code is 200 then i need to preform a segue.

I am running into an issue where the segue is occurring no matter what i try

I have tried using the IBAction for a button then calling preform segue however that resulted in a thread problem. I have now put everything in shouldPerformSegue

override func shouldPerformSegue(withIdentifier identifier: NSStoryboardSegue.Identifier, sender: Any?) -> Bool {

        if emailTextField.stringValue.isEmpty || passwordTextField.stringValue.isEmpty {
            instructionText.stringValue = "Email and Password Required"
            return false
        }

        let emailPassword = "email="+emailTextField.stringValue+"&password="+passwordTextField.stringValue
        print("before post")
        let data = emailPassword.data(using: String.Encoding.ascii, allowLossyConversion: false)
        let url = URL(string: "http://127.0.0.1:50896/api/v1/auth")!
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.httpBody = data
        let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
            if let error = error {
                print("error: \(error)")
            } else {
                if let response = response as? HTTPURLResponse {
                    print("statusCode: \(response.statusCode)")
                }
                if let data = data, let dataString = String(data: data, encoding: .utf8) {
                    print("data: \(dataString)")
                }
            }
        }
        task.resume()

        return true
    }

I would like to complete the post request, check response code then preform segue if the code is 200

Zoneos
  • 1
  • 1
  • 1
    It’s impossible to return something depending on the result of an asynchronous task in `shouldPerformSegue`. – vadian Apr 23 '19 at 15:01

2 Answers2

0

The problem is - The task.resume() is asynchronous; its result is therefore useless, because you are already returning from shouldPerformSegue() with a true value. What that essentially means is that the task is executed sometime AFTER you said "It's ok to perform a segue". Instead, call the task from the buttons IBAction, and perform segue in 200 status code section. Good luck!

Edit: The thread problem with the IBAction is probably because you are doing main-thread stuff on an off-thread (UI updates, performSegue, ...). Check out In Swift how to call method with parameters on GCD main thread?

haste
  • 283
  • 1
  • 9
0

One way of doing it is using with completion callback using closures.

func shouldPerformSegue(withIdentifier identifier: NSStoryboardSegue.Identifier, sender: Any?,OnSucess sucess:@escaping(Bool)->Void){
    let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
        if let error = error {
            print("error: \(error)")
            sucess(false)
        } else
        {
            if let response = response as? HTTPURLResponse {

                print("statusCode: \(response.statusCode)")
            }
            if let data = data, let dataString = String(data: data, encoding: .utf8) {
                print("data: \(dataString)")
            }
            sucess(true)
        }
    }
}

let identiferStory: NSStoryboardSegue.Identifier = "main"
shouldPerformSegue(withIdentifier: identiferStory, sender: nil) { (isSucess) in
    if isSucess == true{

    }
    else{

    }
}
kathmandu
  • 11
  • 4
  • `shouldPerformSegue` is a method of `UIViewController`. If you change the signature it’s never going to be called. – vadian Apr 23 '19 at 16:41
  • Thank you for point that out @vadian. I was unaware of that. In that case maybe you can write another completion callback using closures and call it from shouldPerformSegue function. – kathmandu Apr 23 '19 at 17:16