Dealing with multiple completion handlers
If I understand what are you are trying to do correctly, you probably want to use a DispatchGroup
Here is an example:
let group = DispatchGroup()var letters = ["a", "b", "c"]for letter in letters { group.enter() Server.doSomething(completion: { [weak self] (result) in print("Letter is: \(letter)") group.leave() })}group.notify(queue: .main) { print("- done")}
This will print something like:
bca// ^ in some order- done
First, take note that your service.request(...)
is processed in asynchronous mode. Another problem is you want to finish all the service request in that loop.
My suggestion is create the function with completion handler and add a counter on each loop done. Your function will be similarly as below.
var results = [String:Int]()func requestData(for identifiers: [String], callback:@escaping (Bool) -> Void){ var counter = 0 var maxItem = identifiers.count identifiers.forEach { identifier in service.request(identifier, completion: { (result) in result[identifier] = result counter += 1 if counter == maxItem { callback(true) // update completion handler to say all loops request are done } // if not, continue the other request }) }}
This is how another part of your code will call the function and wait for callback
requestData(for identifiers:yourArrays) { (complete) in if complete { print(results) }}
Don't forget to manage if errors happened.