使用 OperationQueue 处理 URL 请求(内置重试机制)。
以下是 URLRequestOperation
的详细生命周期
首先,对 URL 进行处理以便运行。 这意味着将调用方法 processURLRequestForRunning
。 如果子类想要阻止请求在特定条件下运行,或者如果他们想在运行之前修改 URL 请求,这是一个子类可以重写的地方。
这种处理可能需要一些时间,或者在资源方面非常昂贵,这就是为什么您可以指定一个队列来完成处理的原因。(这是 queueForProcessingURLRequestForRunning
属性。)
如果处理失败(返回错误),操作将进入错误处理步骤 (4),并显示给定的错误(操作可能会稍后重试,具体取决于错误处理结果)。
接下来,创建会话任务。 任务的创建和操作的行为将因提供给操作的 URL 会话的委托而异。
会话委托是 URLRequestOperationSessionDelegate
的一个实例:使用 urlSessionTaskForURLRequest(_:withDelegate)
创建任务(如果需要,可以覆盖)。 默认情况下,在此方法中,会话委托被告知将关于此特定任务的委托方法转发到操作(URL 会话的委托是一个全局委托,如果没有这个技巧,就无法通过任务进行设置 AFAIK)。
如果子类覆盖此方法并决定以不同的方式处理委托方法,它们将负责接收数据并处理数据,然后**必须**在任务完成时调用 urlSession(_:task:didCompleteWithError:)
。
会话委托有点像另一种 nil
类:使用 urlSessionTaskForURLRequest(_:,withDataCompletionHandler:, downloadCompletionHandler:)
创建任务。
最后启动任务。
URLRequestOperationSessionDelegate
的一个实例时errorForResponse(_:)
将检查响应是否合适(正确的状态代码和 MIME 类型或其他预过滤器)。 然后,如果先前的检查通过,将调用 urlResponseProcessor
。 如果他们认为响应不值得继续,这两个方法都可以取消会话任务。urlSession(_:task:didCompleteWithError:)
),任务将完成。 调用 processEndOfTask(error:)
(private) 来检查从此处该怎么做。processEndOfTask(error:)
。processEndOfTask(error:)
)如果已经存在最终错误(例如,操作已取消),则操作在此处结束。
否则,将在 queueForComputingRetryInfo
上调用 computeRetryInfo(sourceError:completionHandler:)
方法(计算重试信息可能是一个昂贵的操作)。 此方法负责说明是否应该重试操作以及在哪个延迟之后重试。 默认实现将检查错误。 例如,对于网络丢失,对于幂等 HTTP 请求应该重试该操作。 默认情况下,延迟遵循指数退避。 子类可以覆盖以实现自己的逻辑和行为。 这实际上是操作最重要的覆盖点。
computeRetryInfo
方法还将允许决定是否应该设置一些“提前重试”技术。 或者您可以设置自己的。 有两种内置的重试技术:ReachabilityObserver
将简单地检查网络何时再次可达,而 Other Success Observer
将在同一主机的另一个 URLRequestOperation 成功时触发重试。
如果您决定编写自己的“提前重试”方法,则应覆盖 removeObserverForEarlyRetrying()
并在您的实现中删除您的观察者。 不要忘记调用 super!
如果告知该操作要重试,当它被重试时,我们只需回到步骤 2。(URL 重新处理等等)
该项目最初由 François Lamboley 在 happn 工作时创建。