Search code examples
iosswiftasynchronousafnetworking-2

AFNetworking User Login asynchron issue


When the user presses the button Login, the login-post request will be send. Then I want to fetch the result from this post request, whether it was successful or not.

My Post-request:

func login (username: String, password: String) -> Bool {
    var param = ["username": username, "password": password]
    POST(APIURL.URL_LOGIN, parameters: param,  
       { (operation : NSURLSessionDataTask!, response : AnyObject!) -> Void in
            println("Login")
        self.defaults.setBool(true, forKey: "USERLOGGEDIN")
        }, { (operation : NSURLSessionDataTask!, error : NSError!) -> Void in
            self.defaults.setBool(false, forKey: "USERLOGGEDIN")
        })

    if (self.defaults.boolForKey("USERLOGGEDIN") == true) {
        return true
    }
    else if (self.defaults.boolForKey("USERLOGGEDIN") == false) {
        return false
    }
    else {
        return false
    }
}

My button call:

@IBAction func login(sender: AnyObject) {
    var username: NSString = userid.text
    var userpassword: NSString = password.text

    //Loginroutine
        var flag = (_sharedAPIManager.login(userid.text, password: password.text)) as Bool

        if ( flag == true) {
           println("correct password")
        } else {
            println("false password")
        }
    }
}

I have to press the login buttons sometimes twice. I think this issue is related to afnetworking using different threads.

How can I solve this issue in an elegant way?


Solution

  • It isn't because AFN is using different threads, it's because you aren't dealing with the fact that it is (and you asked it to) properly. That's because your loving method:

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

    is returning a Bool, but when it returns the asynchronous login won't be complete.

    Instead of returning Bool your function should take a completion block which is called with a Bool parameter, and it should be called from the AFN success and failure blocks (because that's when you know the result status of the login).

    So your login method would be:

    func login (username: String, password: String, completion: ((success: Bool) -> Void)!)
    

    and in the POST response you would have:

    println("Login")
    self.defaults.setBool(true, forKey: "USERLOGGEDIN")
    completion(true)