2017-08-03 14 views
1

準備ができたら結果を返す方法があります。しかし、私は2つの完成ハンドラーで苦労しています。補完ハンドラの問題

これはコードです。最初の完了ハンドラはmembers.observesingleEventです。これは、データベースからいくつかのキーを返します。次に、キーをループして、別の呼び出しから新しい値を取得します。私は値をループし、他の呼び出しを行います。

private func getRoomDevices(completionHandler : @escaping (Bool) ->()){ 


members.observeSingleEvent(of: .value, with: { snapshot in 
    if !snapshot.exists() { return } 

    let postDict = snapshot.value as! [String : AnyObject] 

    for list in postDict { 
     self.ref.child("groups/" + list.key).observeSingleEvent(of: .value, with: { groups in 
      self.rooms.append(FirebaseApi().convertRoomDevices(snap: groups)) 
      print(groups.debugDescription) 


     }); 
    } 

    completionHandler(true) 

}) 

すべてをルームアレイに追加します。しかし、何が起こるのかは、forループがビジーである間にcompletionHandler(true)が呼び出されることです。すべてが完了したら、completionHandlerを呼び出す必要があります。

答えて

3

DispatchGroupを使用する必要があります。これには非同期ループのすべての項目を追加し、グループのすべての項目が実行を終了した場合にのみ完了ハンドラを呼び出します。

members.observeSingleEvent(of: .value, with: { snapshot in 
    if !snapshot.exists() { return } 

    let postDict = snapshot.value as! [String : AnyObject] 
    let group = DispatchGroup() 
    for list in postDict { 
     group.enter() 
     self.ref.child("groups/" + list.key).observeSingleEvent(of: .value, with: { groups in 
      self.rooms.append(FirebaseApi().convertRoomDevices(snap: groups)) 
      print(groups.debugDescription) 
      group.leave() 
     }); 
    } 
    group.notify(queue: DispatchQueue.main) { 
     completion(true) 
    } 

}) 
関連する問題