I want to run a for loop in swift in order, DispatchGroup will fire them together, so I want to use DispatchQueue and DispatchSemaphore to achieve my goal. I failed to make my program work, how can I force them to wait and run one by one?
let dispatchGroup = DispatchGroup()
let dispatchQueue = DispatchQueue(label: "taskQueue")
let dispatchSemaphore = DispatchSemaphore(value: 1)
for c in self.categories {
    dispatchSemaphore.wait()
    dispatchQueue.async(group: dispatchGroup) {
        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()
            }
        }
    }
}
dispatchGroup.notify(queue: dispatchQueue) {
    self.refreshOrderTable { _ in
        self.productCollectionView.reloadData()
        NVActivityIndicatorPresenter.sharedInstance.stopAnimating()
    }
}
Thanks to Palle, here is my final code:
let dispatchGroup = DispatchGroup()
let dispatchQueue = DispatchQueue(label: "taskQueue")
let dispatchSemaphore = DispatchSemaphore(value: 0)
dispatchQueue.async {
    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()
        }
    }
}
 
    