Reputation: 1605
Wracking my brain on this. I have an app using OAuth2 where I request a token which has an expiration. I am trying to figure out the best way to check for the expiration and if it is expired, request a new token before I send my new API request. I have an enum of the Router class from AlamoFire that checks for an access token like so:
UserManager.getUser()?.getUserAccessToken()
That method looks like:
func getUserAccessTokenForRequest() -> String? {
if isTokenValid() {
return self.accessToken
}
else {
var localAccessToken : String?
let request = DataManager.currentRequest as Request?
DataManager.currentRequest?.cancel()
DataManager.refreshToken{ (success, value) in
if success {
if let returnedToken : String = value as? String {
request?.resume()
}
} else {
if let localError: AnyObject = value {
}
}
}
return nil;
}
}
However when I go to resume the initial request, it is nil because it has already completed and received a response that the token was invalid. I am running into the issue of Async tasks completing before I would like them too (because they are async). I am wondering what the best architecture for this would look like. I could check if the token is valid in my data manager before I even make a request. However I don't want to have to do that for every call.
Would overriding the create request method be the best way to go?
Upvotes: 2
Views: 5500
Reputation: 888
Just found this: Alamofire : How to handle errors globally
I did something similar with AFNetworking
a while ago, I guess you can implement something like this for Alamofire
:
// if token was expired refresh it and retry
private class func refreshTokenAndRetry(operation: AFHTTPRequestOperation, success: (response: AnyObject!) -> Void, failure: (error: NSError!) -> Void) {
Client.refreshToken(
success: { (credential: AFOAuthCredential!) -> Void in
if credential != nil {
println("Refreshed token and retrying operation")
var request = operation.request.mutableCopy() as! NSMutableURLRequest
request.addValue(nil, forHTTPHeaderField: "Authorization")
request.addValue("Bearer \(credential.accessToken)", forHTTPHeaderField: "Authorization")
let retryOperation = requestOperationManager.HTTPRequestOperationWithRequest(
request,
success: { (operation: AFHTTPRequestOperation!, responseObject: AnyObject!) in
success(response: responseObject)
},
failure: { (operation: AFHTTPRequestOperation!, error: NSError!) in
failure(error: error)
}
)
retryOperation.start()
}
},
failure: { (error) -> Void in
failure(error: error)
}
)
}
What you're missing is creating a mutable copy of the original request, then set the token in headers and create a new operation with the new request.
Upvotes: 1