检查来自Alamofire和Swift的多个asynchronous响应

我正在编写一个应用程序,它依赖于来自各个站点/服务的数据,并且涉及根据这些不同来源的数据进行计算以生成最终产品。

我写了一个带有两个函数的示例类,它从两个来源收集数据。 我select了不同的function,因为有时候我们根据不同的来源使用不同的authentication方法,但在这个例子中,我已经把它们简化为最简单的forms。 这两个函数都使用Alamofire来启动和处理请求。

然后我有一个初始化函数,它说如果我们已经成功地从两个源收集数据,然后加载另一个nib文件,否则等待几秒钟,如果没有响应已经返回,然后加载服务器错误nib文件。

我试图让这个例子尽可能简单。 本质。 这是我想要遵循的逻辑。 不幸的是,目前这种做法目前还没有实施。

import Foundation class GrabData{ var data_source_1:String? var data_source_2:String? init(){ // get data from source 1 get_data_1{ data_source_1 in println("\(data_source_1)") } // get data from source 2 get_data_2{ data_source_1 in println("\(data_source_1)") } var timer = 0; while(timer<5){ if((data_source_1 == nil) && (data_source_2 == nil)){ // do nothing unless 4 seconds has elapsed if (timer == 4){ // load server error nib } }else{ // load another nib, and start manipulating data } // sleep for 1 second sleep(1) timer = timer+1 } } func get_data_1(completionHandler: (String) -> ()) -> () { if let datasource1 = self.data_source_1{ completionHandler(datasource1) }else{ var url = "http://somewebsite.com" Manager.sharedInstance.request(.GET, url).responseString { (request, response, returnedstring, error) in println("getting data from source 1") let datasource1 = returnedstring self.data_source_1 = datasource1 completionHandler(datasource1!) } } } func get_data_2(completionHandler: (String) -> ()) -> () { if let datasource2 = self.data_source_2{ completionHandler(datasource2) }else{ var url = "http://anotherwebsite.com" Manager.sharedInstance.request(.GET, url).responseString { (request, response, returnedstring, error) in println("getting data from source 2") let datasource2 = returnedstring self.data_source_2 = datasource2 completionHandler(datasource2!) } } } } 

我知道我可以把第二个闭包放在init函数的第一个闭包内,但是,我不认为这是最好的实践,而我实际上是从两个以上的源码中提取的,所以闭包将会是n闭包。

任何帮助找出最好的方法来检查是否有多个数据源给出了有效的答复,并妥善处理,将不胜感激。

比阻塞线程的循环过程更好,您可以使用调度组来跟踪请求何时完成。 因此,在发出每个请求之前“进入”组,请求完成时“离开”组,并设置一个“通知”块/closures,当所有组的任务完成时将被调用。

例如,在Swift 3:

 let group = DispatchGroup() group.enter() retrieveDataFromURL(url1, parameters: firstParameters) { group.leave() } group.enter() retrieveDataFromURL(url2, parameters: secondParameters) { group.leave() } group.notify(queue: .main) { print("both requests done") } 

或者,在Swift 2:

 let group = dispatch_group_create() dispatch_group_enter(group) retrieveDataFromURL(url1, parameters: firstParameters) { dispatch_group_leave(group) } dispatch_group_enter(group) retrieveDataFromURL(url2, parameters: secondParameters) { dispatch_group_leave(group) } dispatch_group_notify(group, dispatch_get_main_queue()) { print("both requests done") } 

另一种方法是将这些请求包装在一个asynchronous的NSOperation子类中(使它们可以被取消,从而控制对并发度的限制等等),但是这更复杂,所以你可能想要像上面那样从调度组开始。