2017-02-09 134 views
1

我尝试用swift 3创建我的第一个项目。Syncronize异步功能

我尝试从我的API获取数据。如果我手动启动该功能,这很好。我需要同步异步请求。

我需要触发我的功能3次,并等待其他人完成。

makeGetCall(URLstring: "api1") 

等待完成

makeGetCall(URLstring: "api2") 

等待完成

makeGetCall(URLstring: "api3") 

设置此背景并触发每5秒。

func makeGetCall(URLstring: String, update: Bool) { 

    let completeURL = "http://myapi/" + URLstring 


    // Set up the URL request 
    guard let url = URL(string: completeURL) else { 
     print("Error: cannot create URL") 
     return 
    } 
    let urlRequest = URLRequest(url: url) 

    // set up the session 
    let config = URLSessionConfiguration.default 
    let session = URLSession(configuration: config) 

    // make the request 
    let task = session.dataTask(with: urlRequest) { 
     (data, response, error) in 
     // check for any errors 
     guard error == nil else { 
      print("error calling GET on /todos/1") 
      print(error as Any) 
      return 
     } 
     // make sure we got data 
     guard let responseData = data else { 
      print("Error: did not receive data") 
      return 
     } 

      // parse the result as XML 
     if URLstring == "devicelist.cgi" { 
      self.readDevice(XMLData: responseData) 
     } 

     if URLstring == "statelist.cgi" { 
      self.readDeviceData(XMLData: responseData, update: update) 
     } 

     if URLstring == "functionlist.cgi" { 
      self.readGewerke(XMLData: responseData) 
     } 
    } 

    task.resume() 

} 

有人可以帮忙。

哈根

这就是我试图完成处理:

override func viewDidLoad() { 
    super.viewDidLoad() 

    makeGetCall(input: "statelist.cgi") { 
     (result: Bool) in 
     print("finished statelist") 

    } 
    makeGetCall(input: "devicelist.cgi") { 
     (result: Bool) in 
     print("finished devicelist") 
    } 


    makeGetCall(input: "functionlist.cgi") { 
     (result: Bool) in 
     print("finished functionlist") 
    } 

} 

func makeGetCall(input: String, completion: @escaping (_ result: Bool) -> Void) { 



    let completeURL = "http://192.168.0.25/addons/xmlapi/" + input 


    // Set up the URL request 
    guard let url = URL(string: completeURL) else { 
     print("Error: cannot create URL") 
     return 
    } 
    let urlRequest = URLRequest(url: url) 

    // set up the session 
    let config = URLSessionConfiguration.default 
    let session = URLSession(configuration: config) 

    // make the request 
    let task = session.dataTask(with: urlRequest) { 
     (data, response, error) in 
     // check for any errors 
     guard error == nil else { 
      print("error calling GET on /todos/1") 
      print(error as Any) 
      return 
     } 
     // make sure we got data 
     guard data != nil else { 
      print("Error: did not receive data") 
      return 
     } 
     completion(true) 

    } 

    task.resume() 


} 

如果我把3个电话一起它的工作,因为它应该。 我的事情也应该有GCD工作,但大多数的例子为迅速2.

makeGetCall(input: "devicelist.cgi") { 
     (result: Bool) in 
     print("finished devicelist") 
     self.makeGetCall(input: "functionlist.cgi") { 
      (result: Bool) in 
      print("finished functionlist") 
      self.makeGetCall(input: "statelist.cgi") { 
       (result: Bool) in 
       print("finished statelist") 

      } 
     } 
    } 

也许现在有人可以提供帮助。

Thanks Hagen

+0

向'makeGetCall()'添加完成处理程序并使用'DispatchGroup'来等待或得到通知。 – shallowThought

+0

我试图解决我的问题,但没有得到工作。有人可以给我建议。 – Hagen

+0

显示您使用完成处理程序尝试过的内容 – shallowThought

回答

1

使用DispatchGroup在事情发生时得到通知。

override func viewDidLoad() { 
    super.viewDidLoad() 

    let stateListGroup = DispatchGroup() 

    stateListGroup.enter() 
    makeGetCall(input: "statelist.cgi") { 
     (result: Bool) in 
     print("finished statelist") 
     stateListGroup.leave() 
    } 

    let deviceListGroup = DispatchGroup() 
    deviceListGroup.enter() 

    // the notify closure is called when the (stateList-) groups enter and leave counts are balanced. 
    stateListGroup.notify(queue: DispatchQueue.main) { 
     self.makeGetCall(input: "devicelist.cgi") { 
      (result: Bool) in 
      print("finished devicelist") 
      deviceListGroup.leave() 
     } 
    } 

    let functionListGroup = DispatchGroup() 
    functionListGroup.enter() 

    deviceListGroup.notify(queue: DispatchQueue.main) { 
     self.makeGetCall(input: "functionList") { 
      (result: Bool) in 
      print("finished functionlist") 
      functionListGroup.leave() 
     } 
    } 

    functionListGroup.notify(queue: DispatchQueue.main) { 
     print("update ui here") 
    } 
} 

打印:

statelist.cgi 
finished statelist 
devicelist.cgi 
finished devicelist 
functionList 
finished functionlist 
update ui here 

也请记住,session.dataTask()完成处理器上调用后台排队,所以我建议派遣completion(true)主队列,以避免意外的行为:

DispatchQueue.main.async { 
    completion(true) 
} 
+0

非常感谢浅思。我将它修改为group.notify(队列:DispatchQueue.main),现在它可以正常工作。 – Hagen

+0

哦,对不起。写在地铁里...修正了在答案更新。在这里,我们通过提高投票/接受答案btw感谢。 – shallowThought