jon*_*ock 12 asynchronous ios data-synchronization swift alamofire
我正在编写一个依赖于来自各种站点/服务的数据的应用程序,并且涉及基于来自这些不同来源的数据执行计算以生成最终产品.
我编写了一个带有两个函数的示例类,它们收集来自两个源的数据.我选择使函数不同,因为有时我们根据源应用不同的身份验证方法,但在这个例子中我只是将它们剥离到最简单的形式.这两个函数都使用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!)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我知道我可以将第二个闭包放在init函数的第一个闭包内,但是,我认为这不是最佳实践,而且我实际上是从两个以上的源中拉出来的,所以闭包将是n封闭深度.
任何有助于找出检查多个数据源是否给出有效响应的最佳方法的任何帮助,以及对此进行适当处理都将非常感激.
Rob*_*Rob 47
比阻塞线程的循环过程更好,您可以使用调度组来跟踪请求何时完成.因此,在发出每个请求之前"输入"该组,在请求完成时"离开"该组,并设置一个"通知"块/闭包,当完成所有组的任务时将调用该块/闭包.
例如,在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")
}
Run Code Online (Sandbox Code Playgroud)
或者,在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")
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是将这些请求包装在异步NSOperation子类中(使它们可以取消,使您可以控制并发度的约束等),但这更复杂,因此您可能希望从如上所示的调度组开始.