URL 请求操作

Platforms SPM compatible License happn

使用 OperationQueue 处理 URL 请求 (带有内置的重试机制)。

如何使用

以下是 URLRequestOperation 的详细生命周期

  1. 初始化。没什么好说的…
  2. 请求启动
    1. 首先,URL 会被处理以便运行。这意味着会调用 processURLRequestForRunning 方法。 如果子类想要阻止请求根据某些条件运行,或者如果他们想要在运行之前修改 URL 请求,这是一个重写点。

      这个处理可能需要一些时间,或者消耗大量的资源,这就是为什么你可以指定一个队列来完成处理。(这就是 queueForProcessingURLRequestForRunning 属性。)

      如果处理失败(返回一个错误),操作将会进入错误处理步骤 (4),并带有给定的错误(操作可能会在之后重试,取决于错误处理结果)。

    2. 接下来,会创建会话任务。任务的创建和操作的行为会因为传递给操作的 URL 会话的代理而有所不同。

      • 会话代理是一个 URLRequestOperationSessionDelegate 的实例:使用 urlSessionTaskForURLRequest(_:withDelegate) 创建任务 (如果需要可以被重写)。 默认情况下,在此方法中,会通知会话代理将关于此特定任务的代理方法转发给该操作(URL 会话的代理是一个全局代理,并且没有此技巧 AFAIK 就不能通过任务设置)。

        如果子类重写此方法并决定以不同的方式处理代理方法,他们将负责接收和处理数据,然后**必须**在任务完成时调用 urlSession(_:task:didCompleteWithError:)

      • 会话代理是另一种类型的 nil:使用 urlSessionTaskForURLRequest(_:,withDataCompletionHandler:, downloadCompletionHandler:) 创建任务。

    3. 最后,任务被启动。

  3. 请求正在进行时
    • 对于数据任务,当会话代理是 URLRequestOperationSessionDelegate 的实例时
      1. 收到 URL 响应。 首先,errorForResponse(_:) 方法会检查响应是否合适(正确的状态代码和 MIME 类型或其他预过滤器)。 如果之前的检查通过,则会调用 urlResponseProcessor。 如果他们认为响应不值得继续,这两种方法都可以取消会话任务。
      2. 然后接收数据…
      3. 在某个时间点 (urlSession(_:task:didCompleteWithError:)),任务将完成。 调用 processEndOfTask(error:)(私有)来检查接下来该怎么做。
    • 对于数据任务,或者代理不是预期类的任务,将没有响应处理。 下一步是任务完成时:调用 processEndOfTask(error:)
  4. 处理任务结束 (processEndOfTask(error:))
    • 如果已经存在最终错误(例如,操作被取消),则在此处结束操作。

    • 否则,会在 queueForComputingRetryInfo 上调用 computeRetryInfo(sourceError:completionHandler:) 方法(计算重试信息可能是一个开销很大的操作)。 此方法负责告知是否应重试操作,以及在哪个延迟之后重试。 默认实现将检查错误。 例如,对于网络丢失,对于幂等的 HTTP 请求应重试该操作。 默认情况下,延迟遵循指数退避。 子类可以重写以实现他们自己的逻辑和行为。 这实际上是该操作最重要的重写点。

      computeRetryInfo 方法还将允许决定是否应设置一些“提前重试”技术。 或者您可以设置您自己的技术。 有两种内置的重试技术:ReachabilityObserver,它将简单地检查网络何时再次可达,以及 Other Success Observer,当另一个针对相同主机的 URLRequestOperation 成功时,它将触发重试。

      如果您决定编写您自己的“提前重试”方法,您应该重写 removeObserverForEarlyRetrying() 并在您的实现中删除您的观察者。 不要忘记调用 super!

      如果操作被告知要重试,当它被重试时,我们只需回到步骤 2。(URL 被重新处理,等等。)

致谢

这个项目最初由 François Lamboleyhappn 工作时创建。