Search code examples
swiftalamofirensurlkey-value-observing

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?


Solution

  • 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
    }