user3069232 user3069232 - 2 months ago 21
Swift Question

A solution to track a batch of HTTP requests in swift 3.0

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, disappears and does it stuff
}


Imagine the async code is a collection of URL requests, that basically background as soon as I loop thru them. Now how can I fire off more code when "rex" requests have completed?

I thought of setting up a timer to watch and check every second, but its surely not a good solution.

I thought kicking off another thread to simply watch the data being collected, and fire when its quota is full, but well that's worse then the timer really.

I am thinking to include a test at the end of each URL request to see if it was the last that completed and than uses the NotificationCenter, but is this the optimal solution?

Answer

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
}