如何在 Alamofire 中处理多个网络调用

How to handle multiple network call in Alamofire

我需要在视图控制器中调用 2 个 api 从服务器获取一些数据,我希望它们同时启动,但只有在它们都返回时才会触发下一步(无所谓这是成功还是失败)。 我可以想出 2 个解决方案: 1. 将它们链接在一起。调用api1,在api1的result handler中调用api2,等待api2的结果 2.设置2个Bool指标变量,创建一个检查函数,如果这两个指标都为真,则执行下一步。在两个Api result handler中,设置相应的指标变量,然后调用检查函数来决定是否可以进行

第一个还不够,我不能说第二个是一个优雅的解决方案。 Alamofire 在 Reactivecocoa 中是否有类似组合信号的东西?或者有更好的解决方案吗?

您的评估 100% 正确。目前,您列出的两个选项实际上是唯一可能的方法。我同意你的看法,根据你的用例,你的第二个选择比第一个好得多。

如果你想将 ReactiveCocoa 与 Alamofire 结合起来,那当然是可能的,但据我所知还没有完成。您还可以调查 PromiseKit 是否能够提供一些帮助,但它还没有与 Alamofire 粘合在一起。尝试将这些库中的任何一个与 Alamofire 响应序列化程序结合起来绝非易事。

换个角度,我真的不认为 ReactiveCocoa 或 PromiseKit 非常适合您的用例,因为您没有链接服务调用,而是 运行 并行调用它们。此外,您仍然需要 运行 所有解析逻辑并确定每个解析逻辑是成功还是失败,然后相应地更新您的应用程序。我要说的是,选项 2 将是迄今为止最好的选择,除非你想全力以赴将 PromiseKit 或 ReactiveCocoa 与 Alamofire 的响应序列化程序结合起来。

以下是我建议的让事情不那么复杂的方法。

import Foundation
import Alamofire

class ParallelServiceCaller {
    var firstServiceCallComplete = false
    var secondServiceCallComplete = false

    func startServiceCalls() {
        let firstRequest = Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["first": "request"])
        firstRequest.responseString { request, response, dataString, error in
            self.firstServiceCallComplete = true
            self.handleServiceCallCompletion()
        }

        let secondRequest = Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["second": "request"])
        secondRequest.responseString { request, response, dataString, error in
            self.secondServiceCallComplete = true
            self.handleServiceCallCompletion()
        }
    }

    private func handleServiceCallCompletion() {
        if self.firstServiceCallComplete && self.secondServiceCallComplete {
            // Handle the fact that you're finished
        }
    }
}

实施非常简洁,易于遵循。虽然我理解你想要摆脱完成标志和回调函数的愿望,但其他选项,如 ReactiveCocoa and/or PromiseKit 仍然会有额外的逻辑,最终可能会使事情变得更复杂。

另一种可能的选择是使用调度组和信号量,但这确实增加了复杂性,但可以使您更接近 ReactiveCocoa 或 PromiseKit 风格的方法。

我希望这有助于阐明一些问题。

DispatchGroup 是并行处理多个依赖请求的好选择

func loadData() {
    let dispatchGroup = DispatchGroup()

    func startRequests() {
        dispatchGroup.enter()
        loadDataRequest1()
        dispatchGroup.enter()
        loadDataRequest2()

        dispatchGroup.notify(queue: .main) { [weak self] in
            // Process your responses
        }


        loadDataRequest1() {
            // Save your response
            dispatchGroup.leave()
        }

        loadDataRequest2() {
            // Save your response
            dispatchGroup.leave()
        }
    }

    startRequests()
}