Reputation: 97
I have a method in my application that is called getAllPosts()
this is a GET
request that gets data, but inside that method I´m doing a POST
request to get the access token
that needs to be passed with the getAllPosts()
request. So basically like this:
func getAllPosts(){
let token = getToken()
Alamofire.request(.GET...)
}
func getToken(){
Alamofire.request(.POST...)
}
So the issue that I´m having is that the getToken
function is called but not completed and the getAllPosts
function makes the GET
request before the token is set.
I´m not sure how to wait for the token to be set in the getToken()
function before I continue with the getAllPosts
request.
Appreciate some help with this issue.
Upvotes: 0
Views: 1708
Reputation: 56
Alamofire is making network requests, and therefore runs asynchronously in a background thread. If you take a look at examples at Alamofire's GitHub page, you will see that they use a syntax like this:
Alamofire.request(.POST ...)
.validate()
.responseString { response in
// This code will be executed after the token has been fetched.
}
So you'll want to do something like this:
func getAllPosts() {
// This notation allows to pass a callback easily.
getToken { appToken in
// Unwrap the value of appToken into constant "token".
guard let token = appToken else {
// Handle the situation if the token is not there
return
}
// The token is available to use here.
Alamofire.request(.GET ...)
...
}
}
/**
Gets the token.
- Parameters:
- callback: Block of code to execute after the token has been fetched.
The token might be nil in case some error has happened.
*/
func getToken(callback: (appToken: String?) -> Void) {
Alamofire.request(.POST ...)
.validate()
.responseString { response in
// Check whether the result has succeeded first.
switch response.result {
case .Success:
// Successful result, return it in a callback.
callback(appToken: response.result.value)
case .Failure:
// In case it failed, return a nil as an error indicator.
callback(appToken: nil)
}
}
}
My answer includes a bit more error handling, but the idea is that you simply use a function inside the .responseString/.responseJSON/etc. call.
@Steelzeh's answer demonstrates the same idea, but instead of calling getAllPosts() first, they call getToken() first, and then pass the result to getAllPosts().
Upvotes: 2
Reputation: 284
Change it to this
func getAllPosts(){
Alamofire.request(.GET...)
}
func getToken(){
Alamofire.request(.POST...) {
//SUCCESS BLOCK
self.getAllPosts()
}
}
Now instead of calling getAllPosts you should first call getToken and when the POST request is complete it goes to the Success Block where it fires getAllPosts() which now has the token.
A different way to solve this would be to make the POST request Synchronised instead of using Alamofire which is Async. Synchronised requests wait for response before continuing
Upvotes: 1