iosswift4nsoperationqueuensoperationswift4.1

How to do two concurrent API calls in swift 4


Thanks in advance for help, I have two API calls, both are concurrent and any call could be success first(I don't want call in sequence), after success of both calls, I have to stop my activity indicator and reload my tableView, Here is my code but I don't know is this the right way or not and how to reload my tableView and stop my activity indicator.

func downloadDetails(){
    let operationQueue: OperationQueue = OperationQueue()
    let operation1 = BlockOperation() {
    WebServiceManager.getAData(format:A, withCompletion: {(data: Any? , error: Error?) -> Void in

          if let success = data {
              DispatchQueue.main.async {
                  (success code)
              }
           }
        })

        let operation2 = BlockOperation() {
        webServiceManager.getBData(format: B, withCompletion: {(data: Any? , error: Error?) -> Void in

                if let success = data {
                    DispatchQueue.main.async {
                       (success code)
                    }
                }
            })
        }
        operationQueue.addOperation(operation2)
    }
    operationQueue.addOperation(operation1)
}
downloadDetails() "calling function"

Solution

  • This is exactly the use case for DispatchGroup. Enter the group for each call, leave the group when the call finishes, and add a notification handler to fire when they're all done. There's no need for a separate operation queue; these are already asynchronous operations.

    func downloadDetails(){
        let dispatchGroup = DispatchGroup()
    
        dispatchGroup.enter()   // <<---
        WebServiceManager.getAData(format:A, withCompletion: {(data: Any? , error: Error?) -> Void in
    
            if let success = data {
    
                DispatchQueue.main.async {
                    (success code)
                    dispatchGroup.leave()   // <<----
                }
            }
        })
    
        dispatchGroup.enter()   // <<---
        webServiceManager.getBData(format: B, withCompletion: {(data: Any? , error: Error?) -> Void in
    
            if let success = data {
    
                DispatchQueue.main.async {
                   (success code)
                   dispatchGroup.leave()   // <<----
                }
            }
        })
    
        dispatchGroup.notify(queue: .main) {
            // whatever you want to do when both are done
        }
    }