Reputation: 99
I'm using Siesta REST API client for swift. I'm logging into an external API (successfully) and get the result from the siesta request object. The request has two callbacks - onSuccess and onFailure.
If the login was successful I set a token in the keychain and then return the result to the view controller - which segues to a new view controller if successful.
However, as I'm assuming the callback is used asynchronously, my function is not returning the correct result.
@IBAction func normalLoginButton(_ sender: UIButton) {
//do normal login
let standardLogin = StandardLogin()
let credentials = ["email" : "[email protected]", "password": "password" ]
let loginResult = standardLogin.login(params: credentials)
print(loginResult)
if loginResult {
performSegue(withIdentifier: "showSuccessfulLoginView", sender: self)
}
}
func login(params : Dictionary<String,String>) -> Bool{
var loginSuccess = false
let loginRequest = wrApi.makePostRequest(route: "login", params:params)
loginRequest
.onSuccess { data in
print("succes")
self.setJwtToken(jsonData: data.content)
loginSuccess = true
}
.onFailure { error in print("an error occured")
}
return loginSuccess
}
My question is basically how do I wait for the callback to finish before returning my loginSuccess Boolean?
I'm pretty new to swift, so any help would be appreciated.
Upvotes: 1
Views: 6357
Reputation: 5554
As @Nguyen points out, you can't return an immediate value from an async function. Given that all you're doing with the return value is performing your segue - just move that call into the completion handler
@IBAction func normalLoginButton(_ sender: UIButton) {
//do normal login
let standardLogin = StandardLogin()
let credentials = ["email" : "[email protected]", "password": "password" ]
standardLogin.login(params: credentials)
}
func login(params : Dictionary<String,String>){
let loginRequest = wrApi.makePostRequest(route: "login", params:params)
loginRequest
.onSuccess { data in
print("success")
self.setJwtToken(jsonData: data.content)
performSegue(withIdentifier: "showSuccessfulLoginView", sender: self)
}
.onFailure { error in print("an error occured")
}
}
Upvotes: 1
Reputation: 1693
login is acsync function, so you can't use return Try closure:
func login(params : Dictionary<String,String>, handleFinish:((isOK:Bool,param: Type?)->())){
var loginSuccess = false
let loginRequest = wrApi.makePostRequest(route: "login", params:params)
loginRequest
.onSuccess { data in
print("succes")
self.setJwtToken(jsonData: data.content)
loginSuccess = true
handleFinish(isOK: true, param :data.content )
}
.onFailure { error in
print("an error occured")
handleFinish(isOK: false, param :nil )
}
}
and call it:
login(param) { (isOK, param) in
if isOK{
print("login success: \(param)")
}
}
Upvotes: 4