3

I'm adopting RequestAdapter and RequestRetrier to add refresh token behavior automatically to my request. The problems that retry occurs indefinitely without control. I have this code:

class AuthHandler: RequestAdapter, RequestRetrier {

    func adapt(_ urlRequest: URLRequest) throws -> URLRequest {

        return urlRequest

    }

    public func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) {

        if let response = request.task?.response as? HTTPURLResponse, response.statusCode == 401 {

            _ = Credential.current.renew({ (credential, error) in
                completion(true, 0.0) /// Retry request
            })

        } else {

            completion(false, 0.0) // Don't retry

        }

    }

}

How can I do the request retry only once after fails?

I tried this:

request.retryCount = 1

but doesn't works... Any idea?

Thanks!

mhergon
  • 1,688
  • 1
  • 18
  • 39

1 Answers1

6

retryCount is read-only. The description for retryCount is:

The number of times the request has been retried.

So, all you need to do is check this retry count, and stop the retry if the retryCount is too high.

To stop after one retry, this code would work:

class AuthHandler: RequestAdapter, RequestRetrier {

    func adapt(_ urlRequest: URLRequest) throws -> URLRequest {
        return urlRequest
    }

    public func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) {

        guard request.retryCount == 0 else { return completion(false, 0) } // relevant change

        if let response = request.task?.response as? HTTPURLResponse, response.statusCode == 401 {

            _ = Credential.current.renew({ (credential, error) in
                completion(true, 0) /// Retry request
            })

        } else {
            completion(false, 0.0) // Don't retry
        }
    }
}

Note: the first time a request is retried, its retryCount is 0. In our code above, we are making sure it's only on its very first retry, where the retryCount == 0.

Hunter Monk
  • 1,967
  • 1
  • 14
  • 25
  • 1
    does anyone know why retry() (alamofire 5) / should() (alamofire 4) is called twice when 401 ? why is it called twice ? – omarojo Jul 19 '19 at 10:11
  • @omarojo, because default request retry count = 2, and when you get error for first time will send second request. Probably yours interceptor has a mistake. Probably you need set newToken in the second request in adapter. –  Dmitriy Greh Dec 08 '20 at 08:43