2016-09-26 90 views
4

我正在使用Alamofire的SessionManager向我的API服务发出请求。Alamofire,会话管理器限制重试次数

有没有办法限制Alamofire的重试次数?

我正在使用新的RequestAdapter和RequestTrier协议在Alamofire v4中提供重试机制。

我想将重试次数限制为5次。如果5次重试后不应该发生新的请求。

class VMRetrier: RequestAdapter, RequestRetrier { 

public func adapt(_ urlRequest: URLRequest) throws -> URLRequest { 
    return urlRequest; 
} 

func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) { 

    if let response = request.task?.response as? HTTPURLResponse, response.statusCode == 401 { 
     VMLogger.shared.debug(message: "Trying to get a token") 
     let _ = AuthService.shared.login(email: "[email protected]", password: "test34") 
          .then(execute: { (response) in 
           completion(true, 0.0) 
          }) 
    } 
    else { 
     completion(false, 0.0) 
    } 
} } 

用法:

internal let sessionManager = SessionManager() 

override init() { 
    super.init() 
    sessionManager.adapter = VMRequestAdapter() 
    sessionManager.retrier = VMRetrier() 
} 

UPDATE 有在alamofire新承诺提供重试次数选项。 Alamofire Commit

+0

你有没有找到任何解决办法? – Footjy

+0

请参阅我的更新 – aymeba

回答

3

我与Alamofire的RequestRetrier协议解决了这个:

class Retrier: RequestRetrier { 

    var defaultRetryCount = 4 
    private var requestsAndRetryCounts: [(Request, Int)] = [] 
    private var lock = NSLock() 

    private func index(request: Request) -> Int? { 
     return requestsAndRetryCounts.index(where: { $0.0 === request }) 
    } 

    func addRetryInfo(request: Request, retryCount: Int? = nil) { 
     lock.lock() ; defer { lock.unlock() } 
     guard index(request: request) == nil else { print("ERROR addRetryInfo called for already tracked request"); return } 

     requestsAndRetryCounts.append((request, retryCount ?? defaultRetryCount)) 
    } 

    func deleteRetryInfo(request: Request) { 
     lock.lock() ; defer { lock.unlock() } 
     guard let index = index(request: request) else { print("ERROR deleteRetryInfo called for not tracked request"); return } 

     requestsAndRetryCounts.remove(at: index) 
    } 

    func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion){ 

     lock.lock() ; defer { lock.unlock() } 

     guard let index = index(request: request) else { completion(false, 0); return } 
     let (request, retryCount) = requestsAndRetryCounts[index] 

     if retryCount == 0 { 
      completion(false, 0) 
     } else { 
      requestsAndRetryCounts[index] = (request, retryCount - 1) 
      completion(true, 0.5) 
     } 
    } 
} 

应该这样使用:

let manager = SessionManager() 
let retrier = Retrier() 
// ... 
manager.retrier = retrier 

然后

let request = manager.request(urlString, method: method, parameters: parameters, encoding: JSONEncoding.default, headers: headers) 

retrier.addRetryInfo(request: request) 

request.response { r in 
    self.retrier.deleteRetryInfo(request: request) 
}.responseApiJSON { (r: DataResponse<JSONObject>) in 
    // You code here 
} 
+0

这将是很好的内置到Alamofire项目 – neoneye

+1

如果我不在这里使用任何会话管理器怎么办?如何去使用请求重载 – Ranjit