在 Alamofire 中处理超时

问题描述

我想用 Alamofire 处理超时错误,如下所示。

  1. 用户通过按下按钮发起请求

  2. 如果发生超时,它将显示带有 2 个按钮的自定义视图的消息(取消和重试)

  3. 如果用户按下 retry_button,请求应该重试

我已经为 Alamofire 配置创建了一个通用类并添加Interceptor Protocol

但我认为请求会在没有用户交互的情况下自动重试。

我的代码如下:

let config = Session.default.session.configuration
config.timeoutIntervalForRequest = 1 

public func retry(_ request: Request,for session: Session,dueto error: Error,completion: @escaping (RetryResult) -> Void) {

       //Todo: How to retry request when retry_button press in custom view
    }

感谢您抽出宝贵时间至少阅读我的问题。

解决方法

解决方案 1

使用没有重试器的不同配置发出请求(没有重试器意味着不会调用 retry 方法)。然后在用户点击重试按钮时重试请求。

var customSessionManager = SessionManager()
customSessionManager.retrier = nil
customSessionManager.request( ... ) {
    // request is being made with no retrier. Hence retry method will not be called.
}

解决方案 2

发出此网络请求时,请从 Alamofire 请求中删除 .validate()。这样,Alamofire 将不会验证响应是否具有不可接受的状态代码。 retry 方法不会被调用,我们可以编写逻辑以在用户按下重试按钮时重试请求。

解决方案 3

(在撰写此答案时,我还没有测试过这种方法。)

如果确实没有办法采用解决方案 1 或解决方案 2,您可以尝试递归调用 retry 方法,同时等待用户单击“取消”或“重试”按钮。当用户点击取消或重试按钮时,在 SingletonClass 中设置一个属性,并在重试方法中使用相同属性的值来确定是重试还是取消该请求。

SingletonClass.retryRequest = false // initial default value
SingletonClass.cancelRequest = false // initial default value
@IBAction func cancelButtonWasPressed(_ sender: AnyObject) {
    SingletonClass.cancelRequest = true
}

@IBAction func retryButtonWasPressed(_ sender: AnyObject) {
    SingletonClass.retryRequest = true
}
public func retry(_ request: Request,for session: Session,dueTo error: Error,completion: @escaping (RetryResult) -> Void) {
    if SingletonClass.retryRequest && !SingletonClass.cancelRequest {
        // This means the user clicked on the Retry button.
        SingletonClass.retryRequest = false // reset the value back to false
        completion(.retry)
    } else if !SingletonClass.retryRequest && SingletonClass.cancelRequest {
        // This means the user clicked on the Cancel button.
        SingletonClass.cancelRequest = false
        completion(.doNotRetry)
    } else {
        // Recursively call the retry method till the user clicks on either the Cancel or Retry button.
        retry(request,for session,dueTo error,completion)
    }
}