0

This may be a bit of an obscure question, but I cannot seem to figure out what is happening here. I have a "login" function that checks a username and password against an API. For some reason, calling this function returns false the first time, but if I call the function a second time, it returns the proper true, assuming I enter the correct credentials.

Here is the function:

if testLogin(usernameTextField.text!, password: passwordTextField.text!) {
            performSegueWithIdentifier("dismissLogin", sender: self)
        } else {
            let alert = UIAlertView()
            alert.title = "Login Problem"
            alert.message = "Wrong username or password."
            alert.addButtonWithTitle("Dismiss")
            alert.show()
        }
    }

The testLogin function appears here;

func testLogin(username: String, password: String) -> Bool {

    let jsonString = "{\"username\":\"\(username)\",\"password\":\"\(password)\"}"
    let myURL = "http://myurl.com/api/login.php"

    let url:NSURL = NSURL(string: myURL)!
    let session = NSURLSession.sharedSession()

    let request = NSMutableURLRequest(URL: url)
    request.HTTPMethod = "POST"
    request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData

    request.HTTPBody = jsonString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")

    let task = session.dataTaskWithRequest(request) {
        (
        let data, let response, let error) in

        guard let _:NSData = data, let _:NSURLResponse = response  where error == nil else {
            print("error")
            return
        }

        do {
            let json:AnyObject? = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)

            if let result = json as? [String: AnyObject] {
                if let status = result["Status"] as! Int? {
                    if status == 200 {
                        self.loginCheck = true
                    } else {
                        self.loginCheck = false
                    }
                }
            }
        } catch {
            print(error)
        }            
    }   
    task.resume()
    return loginCheck
}

Sorry for the length. I can't seem to fathom, though, why calling testLogin the first time returns false, but calling it the second time returns true. Almost as if the function is not calling the website fast enough and is returning false, but the second time I call the function, it has had time to check the website?

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
ZbadhabitZ
  • 2,753
  • 1
  • 25
  • 45
  • Another variation of the "*dataTaskWithRequest is **asynchronous** ..."* theme ... – Martin R Oct 17 '15 at 15:39
  • Thanks @MartinR. This inevitably was a duplicate of the **dataTaskWithRequest is asynchronous** theme, I just didn't realize it. – ZbadhabitZ Oct 18 '15 at 13:50

1 Answers1

1

Your method testLogin is incorrect. Method dataTaskWithRequest is asynchronous. You need to create two callbacks success and failure (closures). Which will be called if request completes. Look at this https://github.com/Alamofire/Alamofire.

Volodymyr
  • 1,037
  • 1
  • 11
  • 27
  • Thanks for the reply. I had actually tried implementing a closure originally, but didn't seem to get the same result. I took some time to further research and it is working properly now; thank you! I'm purposely avoiding using any third-party libraries (like Alamofire), just to learn the basis of how things work on my own. I appreciate the suggestion. – ZbadhabitZ Oct 18 '15 at 13:49
  • No problems. "I'm purposely avoiding using any third-party libraries (like Alamofire)". You can just look at implementation and will do conclusions. – Volodymyr Oct 18 '15 at 14:39