title: Alamofire 5 Adapting and Retrying Requests
body: <p>I am trying to implement my OAuth2 flow using Alamofire 5.0.0-beta.3. As i can see the documentation is still for Alamofire 4 as stated in the github page as well.</p>
  
  <p>I am trying to make the Oauth2 handler following the documentation for Alamofire 4. As the class names are changed, I am completely lost while making it. </p>
  
  <p><strong>This is the code that i am following:</strong></p>
  
  <pre><code>class OAuth2Handler: RequestAdapter, RequestRetrier {
      private typealias RefreshCompletion = (_ succeeded: Bool, _ accessToken: String?, _ refreshToken: String?) -&gt; Void
  
      private let sessionManager: SessionManager = {
          let configuration = URLSessionConfiguration.default
          configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders
  
          return SessionManager(configuration: configuration)
      }()
  
      private let lock = NSLock()
  
      private var clientID: String
      private var baseURLString: String
      private var accessToken: String
      private var refreshToken: String
  
      private var isRefreshing = false
      private var requestsToRetry: [RequestRetryCompletion] = []
  
      // MARK: - Initialization
  
      public init(clientID: String, baseURLString: String, accessToken: String, refreshToken: String) {
          self.clientID = clientID
          self.baseURLString = baseURLString
          self.accessToken = accessToken
          self.refreshToken = refreshToken
      }
  
      // MARK: - RequestAdapter
  
      func adapt(_ urlRequest: URLRequest) throws -&gt; URLRequest {
          if let urlString = urlRequest.url?.absoluteString, urlString.hasPrefix(baseURLString) {
              var urlRequest = urlRequest
              urlRequest.setValue("Bearer " + accessToken, forHTTPHeaderField: "Authorization")
              return urlRequest
          }
  
          return urlRequest
      }
  
      // MARK: - RequestRetrier
  
      func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) {
          lock.lock() ; defer { lock.unlock() }
  
          if let response = request.task?.response as? HTTPURLResponse, response.statusCode == 401 {
              requestsToRetry.append(completion)
  
              if !isRefreshing {
                  refreshTokens { [weak self] succeeded, accessToken, refreshToken in
                      guard let strongSelf = self else { return }
  
                      strongSelf.lock.lock() ; defer { strongSelf.lock.unlock() }
  
                      if let accessToken = accessToken, let refreshToken = refreshToken {
                          strongSelf.accessToken = accessToken
                          strongSelf.refreshToken = refreshToken
                      }
  
                      strongSelf.requestsToRetry.forEach { $0(succeeded, 0.0) }
                      strongSelf.requestsToRetry.removeAll()
                  }
              }
          } else {
              completion(false, 0.0)
          }
      }
  
      // MARK: - Private - Refresh Tokens
  
      private func refreshTokens(completion: @escaping RefreshCompletion) {
          guard !isRefreshing else { return }
  
          isRefreshing = true
  
          let urlString = "\(baseURLString)/oauth2/token"
  
          let parameters: [String: Any] = [
              "access_token": accessToken,
              "refresh_token": refreshToken,
              "client_id": clientID,
              "grant_type": "refresh_token"
          ]
  
          sessionManager.request(urlString, method: .post, parameters: parameters, encoding: JSONEncoding.default)
              .responseJSON { [weak self] response in
                  guard let strongSelf = self else { return }
  
                  if 
                      let json = response.result.value as? [String: Any], 
                      let accessToken = json["access_token"] as? String, 
                      let refreshToken = json["refresh_token"] as? String 
                  {
                      completion(true, accessToken, refreshToken)
                  } else {
                      completion(false, nil, nil)
                  }
  
                  strongSelf.isRefreshing = false
              }
      }
  }
  </code></pre>
  
  <p><strong>This is how to use this for alamofire 4:</strong></p>
  
  <pre><code>let baseURLString = "https://some.domain-behind-oauth2.com"
  
  let oauthHandler = OAuth2Handler(
      clientID: "12345678",
      baseURLString: baseURLString,
      accessToken: "abcd1234",
      refreshToken: "ef56789a"
  )
  
  let sessionManager = SessionManager()
  sessionManager.adapter = oauthHandler
  sessionManager.retrier = oauthHandler
  
  let urlString = "\(baseURLString)/some/endpoint"
  
  sessionManager.request(urlString).validate().responseJSON { response in
      debugPrint(response)
  }
  </code></pre>
  
  <p>This is the link i am following to implement this. 
  <a href="https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#adapting-and-retrying-requests" rel="noreferrer">https://github.com/Alamofire/Alamofire/blob/master/Documentation/AdvancedUsage.md#adapting-and-retrying-requests</a></p>