Barkley
Barkley

Reputation: 6693

Using dispatch queues with multiple async calls

I've got a function with a completion handler, and in within the function Im' making 2 separate async calls.

The pseudo for it is like :

func Foo(completion: ()->()) {
 let dispatchGroup = DispatchGroup()

 for doc in documents {
     dispatchGroup.enter()
     ref.getDocument(completion: { (snapshot, error) in
        //Need another getDocument call here
         let Object = Object(init with snapshot data)
      dispatchGroup.leave()
     }
    } 
   } completion()

What I need to do is add another async call where I've added a comment.

That would make the code look like :

ref.getDocument(completion: { (snapshot, error) in
             userCountRef.getDocuments(completion: { (snap, error) in 
             let Object = Object(init with snapshot data)
          dispatchGroup.leave()
           }
         } completion()

The problem with the 2nd set of code is that my completion handler gets called after the first go through of my for loop.

Basically what I am looking to do is to be able to handle two sets of async calls with a dispatch group. I need the first call to go off, and then with the information with the first call I need to use that to make a second call, then at the end make a class object, loop through completely rinsing and repeating, and then at the very end call my completion.

How can this be accomplished?

Upvotes: 1

Views: 671

Answers (1)

BHendricks
BHendricks

Reputation: 4493

When the second async call depends on the first, but no other first data calls from any other objects within ref, then this should work:

func Foo(completion: ()->()) {
  let dispatchGroup = DispatchGroup()

  for doc in documents {
    dispatchGroup.enter()
    ref.getDocument(completion: { (snapshot, error) in
         userCountRef.getDocuments(completion: { (snap, error) in 
           let Object = Object(init with snapshot data)
           dispatchGroup.leave()
         }
    } 
  }

  // .main here is the main DispatchQueue. Can be any queue desired
  dispatchGroup.notify(.main) {
    completion()
  }
}

This notify will ensure that all the enter's have been matched by a closing leave before calling your completion. See more at the apple docs here.

Upvotes: 2

Related Questions