0

I'm trying to perform a login as follows:

 func login()->Bool
    {
            var result:Bool = false;
            var request = URLRequest(url: URL(string: "http://something.com/authenticate")!)
            request.httpMethod = "POST"
            let postString = "email=\(usernameField.text!)&password=\(passwordField.text!)"
            print("email=\(usernameField.text!)&password=\(passwordField.text!)")
            request.httpBody = postString.data(using: .utf8)
            request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
            let task = URLSession.shared.dataTask(with: request) { data, response, error in
                guard let data = data, error == nil else {
                    // check for fundamental networking error
                    print("error=\(error)")
                    result = false;
                    return
                }
                if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
                    // check for http errors
                    print("statusCode should be 200, but is \(httpStatus.statusCode)")
                    print("response = \(response)")
                    print("request = \(request)")
                    result = false
                }
                let responseString = String(data: data, encoding: .utf8)
                result = true;
                print("responseString = \(responseString)")
                self.processResponse(jsonData:data)
            }
            task.resume()
            return result;
    }

My 'result' variable always resolves to false even if the line result = true is hit.

How to set it to true inside the nested method?

S.Vignesh
  • 111
  • 1
  • 6
  • 1
    Because the Network request is Asynchronous and return result is called before the request is completed. You should use completion handler. Look out for other SO Posts for it. – Bista Dec 30 '16 at 07:10
  • Use completion handler instead of returning bool.And call the completion handler inside datatask block after checking the outpit – user3608500 Dec 30 '16 at 07:12
  • Thanks @Mr.Bista and user36085000 . Completion handler is the answer. – S.Vignesh Dec 30 '16 at 07:24

1 Answers1

1

You are using Block and blocks are not call at the same time when you are calling "login" method. So, you need to implement blocks for receive result. Try Following Code :

func login(block:((Bool) -> Void)!)
{
    var result:Bool = false;
    var request = URLRequest(url: URL(string: "http://something.com/authenticate")!)
    request.httpMethod = "POST"
    let postString = "email=\(usernameField.text!)&password=\(passwordField.text!)"
    print("email=\(usernameField.text!)&password=\(passwordField.text!)")
    request.httpBody = postString.data(using: .utf8)
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {
            // check for fundamental networking error
            print("error=\(error)")
            result = false;
            block(result)
            return
        }
        if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {
            // check for http errors
            print("statusCode should be 200, but is \(httpStatus.statusCode)")
            print("response = \(response)")
            print("request = \(request)")
            result = false
        }
        if data != nil
        {
            result = true
        }
        let responseString = String(data: data, encoding: .utf8)

        print("responseString = \(responseString)")
        self.processResponse(jsonData:data)
        block(result)
    }
    task.resume()
}
Sandeep Kumar
  • 328
  • 1
  • 8