Egle Matutyte
Egle Matutyte

Reputation: 225

swift 3 calling function with completion closure in return

I am new at Swift and I am having some trouble. I am trying to get a value from my request. I can print it as closure, but I want to get as string on a VC and work with it, but on function login. I can't figure out how to return from a closure.

Function with closure:

class Json {
var loginToken = ""


  public func login(userName: String, password: String) -> (Any){

let loginrequest = JsonRequests.loginRequest(userName: userName, password: password)
return makeWebServiceCall(urlAddress: URL, requestMethod: .post, params: loginrequest, completion: { (JSON : Any) in


  //let jsons = JSON
  print("\(JSON)")


})

}


private func makeWebServiceCall (urlAddress: String, requestMethod: HTTPMethod, params:[String:Any], completion: @escaping (_ JSON : Any) -> ()) {


    Alamofire.request(urlAddress, method: requestMethod, parameters: params, encoding: JSONEncoding.default).responseJSON { response in

        switch response.result {
        case .success(let data):
            if let jsonData = response.result.value {
                completion(jsonData)
            }
        case .failure(let error):
            if let data = response.data {
                let json = String(data: data, encoding: String.Encoding.utf8)
                completion("Failure Response: \(json)")

            }

Calling function on VC:

let retur = Json()
    let rezultatas = retur.login(userName: "root", password: "admin01")

    print(rezultatas)

Upvotes: 3

Views: 4577

Answers (2)

ebby94
ebby94

Reputation: 3152

You can't return from a closure. Also, note that your function is making a webservice call. When that part is encountered, the control doesn't go into the block immediately and the entire function execution will be over before the block is executed. Instead of returning a value you can add another completion block to your login function. Add another argument to your login function.

public func login(userName: String, password: String, completion: @escaping(Any)->Void)

Inside the login function, remove the return statement and do something like this

makeWebServiceCall(urlAddress: URL, requestMethod: .post, params: loginrequest, completion: { (JSON : Any) in
    completion(JSON)
})

And when you call your login function all you have to do is,

login(userName: "", password:""){(response) in
    print(response)
}

You'll have the data that you wanted to pass here

Upvotes: 4

torinpitchers
torinpitchers

Reputation: 1292

Your method: public func login(userName: String, password: String) -> (Any) implements a method with a completion handler, specifically: private func makeWebServiceCall (urlAddress: String, requestMethod: HTTPMethod, params:[String:Any], completion: @escaping (_ JSON : Any) -> ()).

This means that the login function will take an unknown amount of time, so it will also need to implement a completion handler (which can be done in a closure) , instead of returning a value (which cannot be done in a closure).

Upvotes: 0

Related Questions