Skip to content
Pascal Pfiffner edited this page Sep 15, 2016 · 8 revisions

Alamofire v4 sports a new RequestRetrier protocol that works perfect with OAuth2 v3. If you're stuck with an older Alamofire version you may try the old way of doing things.

See below for the OAuth2RequestRetrier class that you can drop into your project. Set up your OAuth2 instance as usual, without forgetting to implement handleRedirectURL() (step 3). Then instantiate one SessionManager and set its adapter and retrier, like so:

let sessionManager = SessionManager()
let retrier = OAuth2RetryHandler(oauth2: <# your OAuth2 instance #>)
sessionManager.adapter = retrier
sessionManager.retrier = retrier
self.alamofireManager = sessionManager   // you must hold on to this somewhere

sessionManager.request("https://api.github.com/user").validate().responseJSON { response in
    debugPrint(response)
}

And here's OAuth2RequestRetrier; if you use CocoaPods, use import p2_OAuth2 instead.

import Foundation
import OAuth2
import Alamofire


class OAuth2RetryHandler: RequestRetrier, RequestAdapter {
    
    let loader: OAuth2DataLoader
    
    init(oauth2: OAuth2) {
        loader = OAuth2DataLoader(oauth2: oauth2)
    }
    
    /// Intercept 401 and do an OAuth2 authorization.
    public func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) {
        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? RequestRetryCompletion {
                        comp(nil != authParams, 0.0)
                    }
                }
            }
        }
        else {
            completion(false, 0.0)   // not a 401, not our problem
        }
    }
    
    /// Sign the request with the access token.
    public func adapt(_ urlRequest: URLRequest) throws -> URLRequest {
        guard nil != loader.oauth2.accessToken else {
            return urlRequest
        }
        return urlRequest.signed(with: loader.oauth2)
    }
}

That's it. Happy requesting!

Clone this wiki locally