Skip to content
Brad Dworak edited this page Jan 27, 2021 · 4 revisions

Alamofire v5 supports a new RequestInterceptor protocol that works with OAuth2 v3.

Setup Instructions:

  1. Create your OAuth2 instance as usual.
  2. Make a AF.Session request using your adaptation of the following example below:
AF.request("https://api.github.com/user", interceptor: OAuth2RetryHandler(oauth2: oauth2), requestModifier: { $0.timeoutInterval = 5 }).validate().response() { response in
        debugPrint(response)
    }
  1. Add the following OAuth2RetryHandler class to your Xcode project.
import Foundation
import OAuth2
import Alamofire

class OAuth2RetryHandler: Alamofire.RequestInterceptor {
    
    let loader: OAuth2DataLoader

    init(oauth2: OAuth2) {
        loader = OAuth2DataLoader(oauth2: oauth2)
    }
    
    func retry(_ request: Request, for session: Session, dueTo error: Error, completion: @escaping (RetryResult) -> Void) {
       
        
        if let response = request.task?.response as? HTTPURLResponse, 401 == response.statusCode, let req = request.request {
            var dataRequest = OAuth2DataRequest(request: req, callback: { _ in })
          
            dataRequest.context = completion
            loader.enqueue(request: dataRequest)
            loader.attemptToAuthorize() { authParams, error in
                self.loader.dequeueAndApply() { req in
                    if let comp = req.context as? (RetryResult) -> Void {
                        comp(nil != authParams ? .retry : .doNotRetry)
                    }
                }
            }
        }
        else {
             completion(.doNotRetry)   // not a 401, not our problem
        }
    }
    
    func adapt(_ urlRequest: URLRequest, for session: Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
        guard nil != loader.oauth2.accessToken else {
            completion(.success(urlRequest))
            return
        }
        
        do {
            let request = try urlRequest.signed(with: loader.oauth2)
            
            return completion(.success(request))
        } catch {
            print("Unable to sign request: \(error)")
            return completion(.failure(error))
        }
    }
}
Clone this wiki locally