Wait until swift for loop with asynchronous network requests finishes executing Wait until swift for loop with asynchronous network requests finishes executing swift swift

Wait until swift for loop with asynchronous network requests finishes executing


You can use dispatch groups to fire an asynchronous callback when all your requests finish.

Here's an example using dispatch groups to execute a callback asynchronously when multiple networking requests have all finished.

override func viewDidLoad() {    super.viewDidLoad()    let myGroup = DispatchGroup()    for i in 0 ..< 5 {        myGroup.enter()        Alamofire.request("https://httpbin.org/get", parameters: ["foo": "bar"]).responseJSON { response in            print("Finished request \(i)")            myGroup.leave()        }    }    myGroup.notify(queue: .main) {        print("Finished all requests.")    }}

Output

Finished request 1Finished request 0Finished request 2Finished request 3Finished request 4Finished all requests.


Swift 3 or 4

If you don't care about orders, use @paulvs's answer, it works perfectly.

else just in case if anyone wants to get the result in order instead of fire them concurrently, here is the code.

let dispatchGroup = DispatchGroup()let dispatchQueue = DispatchQueue(label: "any-label-name")let dispatchSemaphore = DispatchSemaphore(value: 0)dispatchQueue.async {    // use array categories as an example.    for c in self.categories {        if let id = c.categoryId {            dispatchGroup.enter()            self.downloadProductsByCategory(categoryId: id) { success, data in                if success, let products = data {                    self.products.append(products)                }                dispatchSemaphore.signal()                dispatchGroup.leave()            }            dispatchSemaphore.wait()        }    }}dispatchGroup.notify(queue: dispatchQueue) {    DispatchQueue.main.async {        self.refreshOrderTable { _ in            self.productCollectionView.reloadData()        }    }}


Xcode 8.3.1 - Swift 3

This is the accepted answer of paulvs, converted to Swift 3:

let myGroup = DispatchGroup()override func viewDidLoad() {    super.viewDidLoad()    for i in 0 ..< 5 {        myGroup.enter()        Alamofire.request(.GET, "https://httpbin.org/get", parameters: ["foo": "bar"]).responseJSON { response in            print("Finished request \(i)")            myGroup.leave()        }    }    myGroup.notify(queue: DispatchQueue.main, execute: {        print("Finished all requests.")    })}