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:) (private) 来检查从此处该怎么做。
    • 对于数据任务或其委托不是预期类的任务,将没有响应处理。 下一步将是任务完成时:调用 processEndOfTask(error:)
  4. 处理任务结束(processEndOfTask(error:)
    • 如果已经存在最终错误(例如,操作已取消),则操作在此处结束。

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

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

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

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

鸣谢

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