2017-02-09 170 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