2016-12-28 12 views
1

次のメソッドを実行すると何らかの理由で、メソッドが完了した後に最初のクエリが実行されます。私はディスパッチブロックを使ってクエリを最初に実行させようとしましたが、クエリは決して実行されず、アプリケーションは単にフリーズします。あなたが何が間違っているか知っていれば教えてください。ディスパッチグループ無し間違った時刻に実行されているFirebaseクエリ

方法:

func loadConversations() { 
    let ref = FIRDatabase.database().reference() 
    let convoRef = ref.child("users").child(FIRAuth.auth()!.currentUser!.uid).child("conversations") 
    var conversationID = [String]() 
    print(1) 
    convoRef.queryOrderedByKey().observeSingleEvent(of: .value, with: { (snapshot) in 
     let enumerator = snapshot.children 
     print(2) 
     while let rest = enumerator.nextObject() as? FIRDataSnapshot { 
      print(3) 
      if let id = rest.value as? String{ 
       conversationID.append(id) 
       print(id) 
      } 
     } 
    }) 
    print(4) 
    print("size: \(conversationID.count)") 
    for id in conversationID { 
    print(5) 
     ref.child("conversations").queryEqual(toValue: id).observeSingleEvent(of: .value, with: { (snapshot) in 
     print(6) 
      if let convo = snapshot.value as? [String : AnyObject] { 
      print(7) 
       let conversation = Conversation() 
       conversation.conversationID = id 
       conversation.name = "Temporary test name" 
       self.Conversations.append(conversation) 
      } 
     }) 
     ref.removeAllObservers() 
    } 
    print(8) 
    self.conversationTableView.reloadData() 
    ref.removeAllObservers() 

} 

これは印刷:ディスパッチ基で

1 
4 
size: 0 
8 
2 
3 
-KZyMMzXmkQC_OF0T08_ 

を:

func loadConversations() { 
    let dispatchGroup = DispatchGroup() 
    let ref = FIRDatabase.database().reference() 
    let convoRef = ref.child("users").child(FIRAuth.auth()!.currentUser!.uid).child("conversations") 
    var conversationID = [String]() 
    print(1) 


    dispatchGroup.enter() 
    convoRef.queryOrderedByKey().observeSingleEvent(of: .value, with: { (snapshot) in 

     let enumerator = snapshot.children 
     print(2) 
     while let rest = enumerator.nextObject() as? FIRDataSnapshot { 
      print(3) 
      if let id = rest.value as? String{ 
       conversationID.append(id) 
       print(id) 
       dispatchGroup.leave() 
      } 
     } 


    }) 

    print(4) 
    dispatchGroup.wait() 
    print("size: \(conversationID.count)") 

    for id in conversationID { 
    print(5) 
     ref.child("conversations").queryEqual(toValue: id).observeSingleEvent(of: .value, with: { (snapshot) in 
     print(6) 
      if let convo = snapshot.value as? [String : AnyObject] { 
      print(7) 
       let conversation = Conversation() 
       conversation.conversationID = id 
       conversation.name = "Temporary test name" 
       self.Conversations.append(conversation) 
      } 
     }) 
    } 
    print(8) 
    self.conversationTableView.reloadData() 
    ref.removeAllObservers() 
} 

これは

1 
4 
を印刷

しかし、それはちょうどフリーズして待ちます。クエリは決して実行されません。

なぜクエリが入力されたように見えないのかわかりません。クエリが入力されると、完全に正常に動作しますが、入力が遅すぎます。どんな助けでも大歓迎です。ありがとう!

答えて

2

これは、基本的にネットワークコールであるため、Firebaseのクエリがバックグラウンドスレッドで実行されるためです。応答がFirebaseから来るまでブロックされます。

応答を受け取るとすぐにブロックを実行するには、クエリ応答内にクロージャを記述する必要があります。これは、それがからと

loadConversations { (array) in 

    //do something with this value and execute next query 
} 
内部で呼び出された場所に戻ってあなたのコールを送信します

func loadConversations(completion:@escaping (Array<String>) -> Void) -> Void { 
    let ref = FIRDatabase.database().reference() 
    let convoRef = ref.child("users").child(FIRAuth.auth()!.currentUser!.uid).child("conversations") 
    var conversationID = [String]() 
    print(1) 
    convoRef.queryOrderedByKey().observeSingleEvent(of: .value, with: { (snapshot) in 
     let enumerator = snapshot.children 
     print(2) 
     while let rest = enumerator.nextObject() as? FIRDataSnapshot { 
      print(3) 
      if let id = rest.value as? String{ 
       conversationID.append(id) 
       print(id) 
      } 
     } 
     completion(conversationID) 
    }) 
} 

関連する問題