-1

-second edit- I'm now using the suggestion from Arpit Jain but how do I call that function? I want the result of the function parsed to a variable.

getToken(completionHandler: { // here I should do something with in
    // what should I do here to pass the result of getToken to variable?
})

-editted original question-

I'm a complete newby on Swift and trying to implement an API (as a learning project). But since I'm not familiar with the syntax I keep getting errors in this PoC.

I have a http request via alamofire and I expect testResult to either contain "succes" or an erro. But the function keeps returning "empty"

And I have no clue why?

func getToken() -> String{
var testResult: String! = "empty"
let url: String! = "https://the.base.url/token"
let parameters: Parameters = [
    "grant_type":"password",
    "username":"the_username",
    "password":"the_password",
    "client_id":"the_clientID",
    "client_secret":"the_secret",
]
Alamofire.request(url, method: .post, parameters: parameters, encoding: URLEncoding(destination: .methodDependent)).validate().responseJSON { response in
    switch response.result {
        case .success:
            testResult = "succes"
        case .failure(let error):
            testResult = error as! String
        }
    }
return testResult // this line gives the error
}
Jeroen Swets
  • 215
  • 1
  • 6
  • 17
  • Aw, sorry! After I read this and add this var testResult: String! = "empty" The result is now "empty". It seems the alamofire request doesn't do anything, or I do not parse the results correctly to the string – Jeroen Swets May 23 '17 at 13:03
  • 1
    You're doing an *asynchronous* request – it will happen after the function returns. Compare https://stackoverflow.com/q/25203556/2976878 & https://stackoverflow.com/q/42425524/2976878 & https://stackoverflow.com/q/40810108/2976878 & https://stackoverflow.com/q/40014830/2976878 & https://stackoverflow.com/q/27081062/2976878 & https://stackoverflow.com/q/31264172/2976878 – Hamish May 23 '17 at 13:05
  • Yes, i figured out that the return of the request was later then the function returns the value. I'll check the link, thanks! – Jeroen Swets May 23 '17 at 13:07

2 Answers2

2

In Swift, Optional is a generic type that can contain a value (of any kind), or no value at all.

In many other programming languages, a particular "sentinel" value is often used to indicate a lack of a value. In Objective-C, for example, nil (the null pointer) indicates the lack of an object.

In Swift, any type can be made optional. An optional value can take on any value from the original type, or the special value nil.

Optionals are defined with a ? suffix on the type:

func getToken(tokenReturned:@escaping (_ stringResponse: String?) -> Void) {
    var testResult: String? = "empty"
    let url: String! = "https://the.base.url/token"
    let parameters: Parameters = [
        "grant_type":"password",
        "username":"the_username",
        "password":"the_password",
        "client_id":"the_clientID",
        "client_secret":"the_secret",
        ]
    Alamofire.request(url, method: .post, parameters: parameters, encoding: URLEncoding(destination: .methodDependent)).validate().responseJSON { response in
        switch response.result {
        case .success:
            testResult = "succes"
        case .failure(let error):
            testResult = error as! String // Crash occurred because you were getting nil here and have not unwrapped testResult
        }
        tokenReturned(testResult)
    }
}

For calling the function :

   self.getToken { (strResponse) in
     // Now in strResponse you will get result of testResult
    }

In your case the completion handler block is not opened. Try calling like this.

Arpit Jain
  • 1,660
  • 12
  • 23
0

You can return nil while asynchronous calling . use closure for return value.

For Example

Note this is for example you can chnage as per your requirement

func getResponseString(url: String, method : HTTPMethod,  parameter : [String : AnyObject],  callback: @escaping  (_ string : String) -> ()) -> Void{

        Alamofire.request(API_PREFIX + url, method: method, parameters: parameter).validate().responseJSON { response in
            switch response.result {
            case .success:
                if let result = response.result.value {
                    let JSON = result as! [String : AnyObject]
                    callback("succes")
                }
            case .failure(let error):
                print(error)
                callback("" as! String)
                UtilityClass .removeActivityIndicator()
            }
        }
    }

Calling

  self .getResponseString(url: "url", method: .post, parameter: ["email":"" as AnyObject]) { (responseString) in
            // responseString your string
        }
KKRocks
  • 8,222
  • 1
  • 18
  • 84