I have a lot of places in the code where Alamofire request/response are handled.
Each of this requests may fail because of some intermittent problem (the most common is flaky network).
I would like to be able to retry requests 3 times before bailing out.
The straightforward method would be to having something like that
var errorCount = 0
func requestType1() {
let request = Alamofire.request(...).responseJSON { response in
if (isError(response) && errorCount < 3) {
errorCount += 1
request1()
}
if (isError(response)) {
handleError()
}
handleSuccess()
}
}
However, I dislike this approach A LOT for multiple reasons. The most obvious is that I will need to implement such code for each request type (and I have something like 15 of them).
I am curios whether there is way to do something like (where the changes are minimal and non intrusive)
let request = Alamofire.request(..., **3**)
Alamofire makes developing networking layers easier, faster and much cleaner. Another great benefit of using it is that it can be studied and its code is available. This can help programmers because it's a well-written framework.
Everything with Alamofire is asynchronous, which means you'll update the UI in an asynchronous manner: Hide the upload button, and show the progress view and activity view. While the file uploads, you call the progress handler with an updated percent.
Alamofire 4.0 has a RequestRetrier
protocol you can use.
https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%204.0%20Migration%20Guide.md#request-retrier
Example:
class OAuth2Handler: RequestAdapter, RequestRetrier {
public func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: RequestRetryCompletion) {
if let response = request.task.response as? HTTPURLResponse, response.statusCode == 401 {
completion(true, 1.0) // retry after 1 second
} else {
completion(false, 0.0) // don't retry
}
// Or do something with the retryCount
// i.e. completion(request.retryCount <= 10, 1.0)
}
}
let sessionManager = SessionManager()
sessionManager.retrier = OAuth2Handler()
sessionManager.request(urlString).responseJSON { response in
debugPrint(response)
}
I've had the same problem, and I got the requests to be retried using the RequestRetrier
, should
method and request.retryCount
. Something like it:
// MARK: - RequestRetry
public func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) {
lock.lock() ; defer { lock.unlock() }
if let response = request.task?.response as? HTTPURLResponse{
if response.statusCode == 401 {
requestsToRetry.append(completion)
getToken { (expires, _) in
_ = SessionCountdownToken.sharedInstance.startCount(expirationTime: expires)
}
} else {
if request.retryCount == 3 { completion(false, 0.0 ); return}
completion(true, 1.0)
return
}
} else {
completion(false, 0.0)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With