2017-01-17 5 views
0

Я использую RequestRetrier, чтобы автоматически обновлять access_token для моего API. Но в каждой функции запроса я хотел бы поймать ошибку тайм-аута, но .case(let error) в .responseJSON тело никогда не выполняется, из-за (я думаю) retrier, что я добавляю к своему accessSessionManager. Вот как это выглядит:Alamofire RequestRetrier с обработкой ошибок таймаута

lazy var accessSessionManager: SessionManager = { 
    let configuration = URLSessionConfiguration.default 
    configuration.timeoutIntervalForRequest = Configuration.timeout 
    configuration.timeoutIntervalForResource = Configuration.timeout 
    let sessionManager = Alamofire.SessionManager(configuration: configuration) 
    let oAuth2Handler = OAuth2Handler() 
    sessionManager.retrier = oAuth2Handler 
    sessionManager.adapter = oAuth2Handler 
    return sessionManager 
}() 


func changeName(newName: String,completionHandler: ((_ success: Bool, _ error: String?) ->())?) { 
    guard let accessToken = self.getAccessToken() else { return } 
    let parameters = ["access_token": accessToken, "name": newName] as [String : Any] 
    self.accessSessionManager.request(Constants.nameUrl, method: .get, parameters: parameters).responseJSON { response in 
      switch response.result { 
      case .success(let json): 
       let jsonDict = JSON(json) 
       if let success = jsonDict["success"].bool { 
        completionHandler?(success, nil) 
       } 

      case .failure(let error): 
       if error._code == NSURLErrorTimedOut { 
        completionHandler?(false, "Please check your Internet connection and try again!") 
       } else if response.response?.statusCode == 400 { 
        completionHandler?(false, "Sorry, name not found") 
       } else if response.response?.statusCode != 401 { 
        completionHandler?(false, error.localizedDescription) 
       } 
      } 
     } 
    } 
} 

.... 
.... 
class OAuth2Handler { 

//MARK: - Adapter 
    func adapt(_ urlRequest: URLRequest) throws -> URLRequest { 
    if let url = urlRequest.url { 
     guard let accessToken = self.getAccessToken() else { return urlRequest } 
     let newUrl = addOrUpdateQueryStringParameter(url: "\(url)", key: "access_token", value: accessToken) 
     let newRequest = URLRequest(url: URL(string: newUrl)!) 
     return newRequest 
    } 

    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 { 
     if 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.updateAccessToken(accessToken: accessToken, refreshToken: refreshToken) 
        } 
        strongSelf.requestsToRetry.forEach { $0(succeeded, 0.0) } 
        strongSelf.requestsToRetry.removeAll() 
       } 
      } 
     } else { 
      completion(false, 0.0) 
     } 
    } 
} 

Таким образом, в основном ошибка обработки выполняет в should функции, а не в .case(let error) в моей функции.

ответ

0

Вы не подтверждаете ваш запрос. Таким образом, каждый запрос будет успешным. Попробуйте подтверждающей ваш запрос, добавив Validate() после запроса, но до ответа:

self.accessSessionManager.request(...).validate().responseJSON { ... } 

Вы можете найти пользовательские способы изменить поведение, что и что не принимается функцией validate() в их readme

+0

если ответ будет завершена, она будет идти к успеху, но когда я пытаюсь поймать ошибку тайм-аут, реакция является незавершенной, так что добавление Validate() не помогает, даже если указать диапазон кода ошибки. –

0

Итак, есть моя очень глупая ошибка, в основном completion(false,0,0) не был выполнен, если error произошел в should функции. Все работает, если это выглядит примерно так:

// 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 { 
     if 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.updateAccessToken(accessToken: accessToken, refreshToken: refreshToken) 
        } 
        strongSelf.requestsToRetry.forEach { $0(succeeded, 0.0) } 
        strongSelf.requestsToRetry.removeAll() 
       } 
      } 
     } else { 
      completion(false, 0.0) 
    } else { 
     completion(false,0.0) 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^