swift – 使用Alamofire对不同的API进行多次调用 – 如何将结果
我正在开发一个应用程序,它使用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] = [] 怎么处理呢? 解决方法
你说:
您实际上可以继续将项目附加到完成处理程序内的数组中.并且由于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) } 现在,您可能希望以不同方式处理错误,但这应该说明基本思路:只需将结果附加到完成处理程序中,然后使用调度组知道所有请求何时完成,并在通知闭包中执行任何计算想. 显然,上面的代码并不关心这些异步任务的完成顺序.如果您确实关心,则需要稍微调整一下(例如将结果保存到字典中,然后构建排序数组).但是如果你只是对结果求平均值,那么顺序并不重要,而且上面的内容相当简单. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |