I started studying Swift and Alamofire. But I ran into a problem with RequestInterceptor: retry func doesn't work. My Request Interceptor:
class MyRequestInterceptor: RequestInterceptor {
// MARK: - ADAPT
func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
print("-------ADAPT---------")
var request = urlRequest
guard let token = TokenService.getAccess() else {
return
}
let bearerToken = "Bearer \(token)"
request.setValue(bearerToken, forHTTPHeaderField: "Authorization")
completion(.success(request))
}
// MARK: - RETRY
func retry(_ request: Request, for session: Session, dueTo error: ApiError, completion: @escaping (RetryResult) -> Void) {
print("--------RETRY-------")
guard let refresh = TokenService.getRefresh() else {
completion(.doNotRetry)
return
}
let parameter = Refresh(token: refresh)
AF.request(ApiManager.refresh.path, method: .post, parameters: parameter)
.responseDecodable(of: TokensPair.self) { response in
guard let tokens = response.value else {
completion(.doNotRetry)
return
}
TokenService.setAccess(token: tokens.access)
TokenService.setRefresh(token: tokens.refresh)
completion(.retry)
}
}
}
My Session Manager:
class SessionManager {
static let shared = SessionManager()
let sessionManager: Session = {
let configuration = URLSessionConfiguration.af.default
configuration.timeoutIntervalForRequest = 30
configuration.waitsForConnectivity = true
return Session(
configuration: configuration,
interceptor: MyRequestInterceptor()
)
}()
}
My request:
func checkUser(complition: @escaping (Result<User, ApiError>) -> Void) {
SessionManager.shared.sessionManager.request(ApiManager.me.path).validate().responseDecodable(of: User.self) {
response in
guard let user = response.value else {
complition(.failure(.invalidCred))
return
}
complition(.success(user))
}
}
Adapt work correctly. But retry never works. What am I doing wrong?
I'm using validate()
and expect the status code: 401 to cause an error that will cause a retry, but it doesn't work.
I think problem in retry implementation. Because when i try replace
class MyRequestInterceptor: RequestInterceptor
to
class MyRequestInterceptor: RequestRetrier, RequestAdapter
I get error:
Type 'MyRequestInterceptor' does not conform to protocol 'RequestRetrier'
But i don't know why. And I didn't find solution.
I use: Xcode 13.2.1, Swift: 5, Alamofire: 5.4.4.
Thanks!
You used
ApiError
in theretry
method signature, which breaks the conformance. It works withRequestInterceptor
because that type provides a default implementation. Match the proper signature, ensure you have no local types shadowing the types in the signature, and it should work correctly.