有没有办法做Alamofire请求重试

在处理Alamofire请求/响应的代码中有很多地方。

由于一些间歇性问题(最常见的是片状networking),每个请求可能会失败。

我希望能够在救援前三次重试请求。

直截了当的方法将是有这样的事情

var errorCount = 0 func requestType1() { let request = Alamofire.request(...).responseJSON { response in if (isError(response) && errorCount < 3) { errorCount += 1 request1() } if (isError(response)) { handleError() } handleSuccess() } } 

但是,我不喜欢这种方法很多原因。 最明显的是我需要为每个请求types实现这样的代码(我有类似的15个)。

我很好奇是否有办法做一些像(其中的变化是最小的和非侵入性的)

 let request = Alamofire.request(..., **3**) 

你用Swift得到的语法糖之一是你可以使用这个:

 public func updateEvents(someNormalParam: Bool = true, someBlock: (Void->Void)) 

喜欢这个:

 updateEvents(someNormalParam: false) {...} 

请注意,该块在updateEvents函数的()之外,与您通常所期望的相反。 它只有在块是function声明中的最后一项时才起作用。

这意味着,如果您碰巧遇到了像Alamofire请求那样的阻止,则可以使用您的重试function有效地包装它。 一个稍微复杂的问题是你想调用块内的块。 没什么大不了的:

 func retryWrapper(alamoBlock: (Void->Request)) { alamoblock().responseJSON() { //Your retry logic here } } 

你这样使用它:

 retryWrapper() { Alamofire.request(method, targetUrl, parameters: parameters, encoding: encoding) } 

意味着你所要做的就是find你的Alamofire调用,并把它们包装在{}中,并把retryWrapper()放在前面。 重试逻辑本身只有一次。

Alamofire 4.0有一个你可以使用的RequestRetrier协议。

https://github.com/Alamofire/Alamofire/blob/master/Documentation/Alamofire%204.0%20Migration%20Guide.md#request-retrier

例:

 class OAuth2Handler: RequestAdapter, RequestRetrier { public func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: RequestRetryCompletion) { if let response = request.task.response as? HTTPURLResponse, response.statusCode == 401 { completion(true, 1.0) // retry after 1 second } else { completion(false, 0.0) // don't retry } } } let sessionManager = SessionManager() sessionManager.retrier = OAuth2Handler() sessionManager.request(urlString).responseJSON { response in debugPrint(response) } 

我有同样的问题,请求被重试使用RequestRetrier,方法和request.retryCount 。 像这样:`// MARK: – RequestRetry

 public 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) getToken { (expires, _) in _ = SessionCountdownToken.sharedInstance.startCount(expirationTime: expires) } } else { if request.retryCount == 3 { completion(false, 0.0 ); return} completion(true, 1.0) return } } else { completion(false, 0.0) } }` 

那么我做了以下事情,如果请求失败,我发送一个失败的通知谁提出请求。 然后它负责重试请求。 发现这很容易。

 Alamofire.request(.GET, urlString, parameters: params, headers: defaultHeaders) .validate() .responseJSON { response in switch response.result { case .Success: print("Request Successful") let json = JSON(data:response.data!) NSNotificationCenter.defaultCenter().postNotificationName(SUCCESS_NOTIFICATION, object: movieArray) case .Failure(let error): print("Request Failed with error \(error)") NSNotificationCenter.defaultCenter().postNotificationName(FAILURE_NOTIFICATION, object: error) } }