I am using swift 3.0 running under iOS 10.0 and I want to craft some code that fires when a batch condition is met.
for i in 0 ..< rex {
async code, disapp
While OperationQueue
(aka NSOperationQueue
) is a good choice in many cases, it's not suitable for your use case. The problem is that URL requests are called asynchronously. Your NSOperation
will finish before you get a response from the webservice.
Use DispatchGroup
instead
let group = DispatchGroup()
// We need to dispatch to a background queue because we have
// to wait for the response from the webservice
DispatchQueue.global(qos: .utility).async {
for i in 0 ..< rex {
group.enter() // signal that you are starting a new task
URLSession.shared.dataTask(with: urls[i]) { data, response, error in
// handle your response
// ....
group.leave() // signal that you are done with the task
}.resume()
}
group.wait() // don't ever call wait() on the main queue
// Now all requests are complete
}
What you're looking for is NSOperationQueue
(or OperationQueue
in Swift 3). Here's a Swift tutorial (might be a bit out of date). Here's Apple's documentation on it -- in Swift 3 they drop all the NS prefixes, so it's OperationQueue
/ Operation
.
Basically you should add each of your URL tasks as an Operation
to an OperationQueue
, and have a "done" Operation
with each of your URL tasks as a dependency, and add it to the queue. Then as soon as all your URL tasks are done, it will call your done operation, which you can set up to do whatever you want.
You will probably need to subclass Operation
so you can update the isExecuting
and isFinished
properties properly. This question may be of some help here.
So I'm pretty sure what you want can be found here. Basically you want to use GCD and have a completion closure. It's one line of code, which always makes me giggle. A longer post on the topic is here.