Alamofire 4

yonihemi edited this page Sep 10, 2018 · 5 revisions

Alamofire v4 supports a new RequestRetrier protocol that works perfectly 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 try urlRequest.signed(with: loader.oauth2)   // "try" added in 3.0.2
    }
}

That's it. Happy requesting!

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.