I have a PLP page, I need to hit stock API for all the products visible in screen, and Need to update the stock UI for each product once received the response for every product, I have implemented this using Dispatch Semaphore but faced crash when navigating between screens and I tried using Operation queue but in that I am getting the response at cumulative time of all the API hits. Even I tried with Dispatch group, it also responds same as Operation queue.

One API is taking around half second so each product stock should be updated in half to 1 second is what I need, Any help appreciated.

Tried code using Operation Queue

var queue: OperationQueue?
queue = OperationQueue()
queue?.qualityOfService = .background

productListView.sendCBRClosure = { [unowned self] cbrCodeArray in
        queue?.maxConcurrentOperationCount = 5
        for cbrCode in cbrCodeArray {
            queue?.addOperation {
               self.getStockDetail(cbrCode: cbrCode) // API call
            }
        }
    }

Tried code using Dispatch Semaphore

var semaphore = DispatchSemaphore(value: 4)
productListView.sendCBRClosure = { [weak self] cbrCodeArray in
        DispatchQueue.global().async { [weak self] in
            for cbrCode in cbrCodeArray {
               //API call
               self?.getStockDetail(cbrCode: cbrCode) { qtyStr in
                   self?.semaphore.signal() // after API response received
               }
               self?.semaphore.wait()
            }
       
1

There are 1 best solutions below

5
On

Apple's networking calls using URLSession already run asynchronously on a background thread. There's no reason to need operation queues, DispatchQueue, etc.

Just submit a separate request for each item, and have the response handling code update the UI in a call to the main thread. (You can't do UIKit calls from a background thread.)

Each network operation will run separately and invoke it's completion handler once it's done.