-1

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()
            }
       
R. Mohan
  • 2,182
  • 17
  • 30

1 Answers1

1

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.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • Hi @Duncan C, I am using Alamofire, Tried to hit the API's without any queues, Receiving response after 10-15 seconds. One API hit in postman is taking around 1 second only. I am not getting response for every second, means completion handler invoked after getting all the responses only, I want the completion handler to be invoked for every API response received – R. Mohan Jul 27 '22 at 12:14
  • @R.Mohan you can use dataTaskPublisher or await dataTask to handle each network call. – cora Jul 27 '22 at 12:25
  • @cora could you help me with the code which I have in the question, to implement / use await dataTask, because I haven't used it, I googled but it seems different to use for my code – R. Mohan Jul 27 '22 at 12:33
  • Your code needs to be scrapped. Search for TaskGroup. You can spawn multiple tasks that do network calls and then process responses as they come in. Even WWDC has a video on this, Structured Concurrency – cora Jul 27 '22 at 12:41
  • 1
    So your question is really “How do I get Alamofire to not batch my requests”. Since the advent of URLSession I stopped using Alamofire. I think it just adds an extra layer of indirection and confusion, and not much value. So my short answer to the “how do I work around the limitations of Alamofire” question would be “stop using Alamofire” – Duncan C Jul 27 '22 at 14:17