gpt4 book ai didi

swift - 使用 Alamofire 多次调用不同的 API - 如何将结果保存到数组中?

转载 作者:搜寻专家 更新时间:2023-10-31 08:25:12 26 4
gpt4 key购买 nike

我正在开发一个应用程序,它使用 Alamofire 从几个不同的 API 获取数据(每个调用都是使用一个函数完成的)。然后我必须将所有结果(在我的例子中是 Double 类型)收集到一个数组中以计算平均值。

只要 Alamofire 使用异步调用,就不可能简单地从调用内部将新值附加到数组。

这是一个函数,它调用负责通过 Alamofire 获取数据的每个函数:

func collectData() {
fetchFromFirstAPI()
fetchFromSecondAPI() //etc.
}

下面是其中一个函数的示例:

func fetchFromFirstAPI() {
let APIKey = "XXXXXXXXX"
let APIURL = "http://urlapi.com/api" as URLConvertible

let parameters: Parameters = ["APPKEY": APIKey]

Alamofire.request(APIURL, method: .get, parameters: parameters, encoding: URLEncoding.default).validate().responseJSON { response in
switch response.result {
case .success(let data):
let json = JSON(data)
if let result = json["main"]["value"].double {
myArray.append(result)
} else {
print("error")
}
case .failure:
print("error")
}
}
}

和数组:

var myArray: [Double] = []

如何处理?

最佳答案

你说:

As long as Alamofire uses asynchronous calls, it is impossible to simply append new value to an array from inside of call.

您实际上可以继续将项目附加到完成处理程序中的数组。并且由于 Alamofire 默认在主队列上调用其完成处理程序,因此不需要进一步的同步。您可以使用调度组来了解所有请求何时完成。首先,我会给我的方法完成处理程序,以便我知道它们何时完成,例如:

func fetchFromFirstAPI(completionHandler: @escaping (Double?, Error?) -> Void) {
let APIKey = "XXXXXXXXX"
let APIURL = "http://urlapi.com/api"

let parameters: Parameters = ["APPKEY": APIKey]

Alamofire.request(APIURL, parameters: parameters).validate().responseJSON { response in
switch response.result {
case .success(let data):
let json = JSON(data)
if let result = json["main"]["value"].double {
completionHandler(result, nil)
} else {
completionHandler(nil, FetchError.valueNotFound)
}
case .failure(let error):
completionHandler(nil, error)
}
}
}

在哪里

enum FetchError: Error {
case valueNotFound
}

然后您可以执行以下操作:

func performRequestsAndAverageResults(completionHandler: @escaping (Double?) -> ()) {
var values = [Double]()
let group = DispatchGroup()

group.enter()
fetchFromFirstAPI { value, error in
defer { group.leave() }
if let value = value { values.append(value) }
}

group.enter()
fetchFromSecondAPI { value, error in
defer { group.leave() }
if let value = value { values.append(value) }
}

group.notify(queue: .main) {
completionHandler(self.average(values))
}
}

func average<T: FloatingPoint>(_ values: [T]) -> T? {
guard values.count > 0 else { return nil }

let sum = values.reduce(0) { $0 + $1 }
return sum / T(values.count)
}

现在,您可能想要以不同的方式处理错误,但这应该说明了基本思想:只需将结果附加到完成处理程序中,然后使用调度组来了解所有请求何时完成,并在通知闭包中执行任何你想要的计算。

显然,上面的代码并不关心这些异步任务的完成顺序。如果您确实在意,则需要稍微调整一下(例如,将结果保存到字典中,然后构建一个排序数组)。但是,如果您只是对结果求平均值,则顺序无关紧要,上面的内容相当简单。

关于swift - 使用 Alamofire 多次调用不同的 API - 如何将结果保存到数组中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40966021/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com