【问题标题】:How to cancel multiple networking requests using Moya如何使用 Moya 取消多个网络请求
【发布时间】:2026-02-22 10:10:02
【问题描述】:

我目前正在使用Moya 来构建我的网络调用。根据他们的docs,我将其配置如下:

enum SomeAPIService {
    case endPoint1(with: Object)
    case endPoint2(duration: Int)
}

调用端点时(在本例中为endPoint1),我执行以下操作:

let provider = MoyaProvider<SomeAPIService>()
provider.request(.endPoint1(object: object)) { (result) in
switch result {
    case let .success(moyaResponse):
        finished(Result.success(value: moyaResponse.value))
    case let .failure(error):
        let backendError = BackendError(localizedTitle: "", localizedDescription: "Some error", code: moyaResponse.statusCode)
        finished(Result.failure(error: backendError))
    }
})

我的目标是,在用户执行操作时,取消所有正在发生的网络请求

因此,Moya 确实允许人们取消来自讨论 here 的请求。在点赞最多的评论中,有人提到了let request_1 = MoyaRequestXXXXX,然后是ruest_1.cancel()

我的问题是:

  1. 如何保留指向请求的指针?
  2. provider 没有 cancel() 函数 - 那我应该如何调用它?

非常感谢任何帮助。

编辑:

根据有关使用 [Cancellable] 的有用建议,我做了以下操作:

(1) 在我的应用程序的单例实例Operator 中,我添加了var requests = [Cancellable]() (2) 每个 API 调用都作为 Cancelable 添加到 requests 数组中,如下所示:

let provider = MoyaProvider<SomeAPIService>()
Operator.shared.requests.append(provider as! Cancellable) //causing error
provider.request(.endPoint1(object: object)) { (result) in
//rest of the block omitted 

我认为我的语法不正确,我添加的是提供者而不是请求。但是,既然请求本身就是一个块,那么添加请求的地方在哪里呢?

【问题讨论】:

    标签: ios swift networking alamofire moya


    【解决方案1】:

    request 方法返回一个Cancellable。从文档中我们可以阅读:

    request() 方法返回一个 Cancellable,它只有一个公共函数 cancel(),您可以使用它来取消请求。

    所以根据这个,我做了一个简单的测试和调用:

    var requests: [Cancellable] = []
    @objc func doRequests() {
        for i in 1...20 {
            let request = provider.request(MyApi.someMethod) {
                result in
                print(result)
            }
            requests.append(request)
        }
        requests.forEach { cancellable in cancellable.cancel() } // here I go through the array and cancell each request.
        requests.removeAll()
    }
    

    我使用Charles 设置了一个代理,它似乎按预期工作。未发送任何请求 - 每个请求都已取消。

    所以,你的问题的答案是:

    1. 您可以将其保存在[Cancellable] 数组中。
    2. 遍历数组并取消您要取消的每个请求。

    编辑

    主要问题是您将提供程序添加到数组中并尝试将provider 映射为Cancellable,从而导致错误。 您应该将请求添加到数组中。下面你可以看到实现。

    let provider = MoyaProvider<SomeAPIService>()
    let request = provider.request(.endPoint1(object: object)) { // block body }
    Operator.shared.requests.append(request)
    //Then you can cancell your all requests.
    

    【讨论】:

    • 感谢您的建议。我在问题正文中添加了更多作为响应 - 它与添加请求的语法有关。主要问题是块语法 - 请求是块,我不知道在我的 [Cancellable] 数组中添加请求的位置是合适的。
    • 啊完美。非常感谢!
    【解决方案2】:

    我只想取消当前的提供者会话 + 任务:

    provider.manager.session.invalidateAndCancel()
    

    【讨论】:

    • 我在这里遇到了一个问题,如果您想在取消后发出进一步的请求 - 在任何其他视图控制器上,swift 会抛出有关先前无效请求的错误。
    • @RowanGontier 这有点不具体...... alamofire 正在为你终止与invalidateAndCancel() 的会话,这样你就不应该有任何问题,就像你描述的那样。你应该看看线程,不要在你的视图控制器中处理网络东西。
    • 对我来说有一个不同之处,可能是我使用的是provider.rx,而不是provider.request。