Reputation: 13
What I'm trying to do is sequentially execute a for loop where I wait for the completionHandler() before starting the next iteration.
Code:
// we're on the main queue
for index in 0..<count {
var outcome: Any?
let semaphore = DispatchSemaphore(value: 0)
let queue = DispatchQueue(label: "\(index) iteration")
// this will access a UI component and wait for user to
// enter a value that's passed to the completion handler
funcWithCompletionHandler() { [weak self] (result) in
outcome = result
semaphore.signal()
}
// wait here for the completion handler to signal us
queue.sync {
semaphore.wait()
if let o = outcome {
handleOutcome(outcome)
}
}
// now, we iterate
}
I've tried a lot of other solutions I see here, nothing seems to work.
Upvotes: 1
Views: 487
Reputation: 3256
I prefer working with a background group, you can make an instance of it on your class like this:
var group = DispatchGroup()
DispatchQueue.global(qos: .background).async {
self.group.wait()
// this part will execute after the last one left
// .. now, we iterate part
}
for index in 0..<count {
var outcome: Any?
let queue = DispatchQueue(label: "\(index) iteration")
funcWithCompletionHandler() { [weak self] (result) in
if let strongSelf = self {
outcome = result
strongSelf.group.enter() // group count = 1
}
}
queue.sync {
if let o = outcome {
handleOutcome(outcome)
self.group.leave()
// right here group count will be 0 and the line after wait will execute
}
}
}
Upvotes: 1