Search code examples
swiftfor-looprequestalamofiredispatch-async

How to get notified after looping through Alamofire requests using DispatchQueue in Swift?


I have this code to get a list of ids and names that are parsed from a JSON through an iteration of calls.

Problem is I don't know how to get notified, a simples print("finished"), would do. I tried to use print command after the 'for' loop but it also iterates.

Anyone with any idea?

Here's the code:

override func viewDidLoad() {
    super.viewDidLoad()

    //Manager
    let manager = SessionManager.default.startRequestsImmediately = false

    //País
    let paisRequest = Alamofire.request(self.cadastro_pais_url, method: .post, parameters: self.cadastro_pais_params).responseString { response in

        do { } catch { print("error") }
    }

    for i in 0...2000 {
        DispatchQueue.main.async {

            let patrocinadorRequest = Alamofire.request(self.buscaPatrocinador, method: .post, parameters: ["patrocinador":"\(i)"]).responseJSON { (responseData) -> Void in
                if((responseData.result.value) != nil) {
                    let swiftyJsonVar = JSON(responseData.result.value!)

                    if !(swiftyJsonVar["integracao"] == JSON.null){
                        print("\(swiftyJsonVar["integracao"]),\(swiftyJsonVar["nome"]),")

                    } else {}
                } else {
                    print("Error")
                }
            }

            //Requests Chain
            let chain = RequestChain(requests: [paisRequest, patrocinadorRequest])
            chain.start { (done, error) in

            }
        }
    }
}

Solution

  • The network request should not be done on the main thread, but instead on the background one, sync or async. The main thread is reserved only for the UI stuff, except if you want to force blocking the User interface. You can use Dispatch Group and DispatchQueue to organise you code and notification after completion. The same result could be achieved with the Semaphore...

    Sample:

    let dispatchGroup = DispatchGroup()
    // change the quality of service based on your needs
    let queue = DispatchQueue(label: "com.stackoverflow", qos: .background)
    
    for i in 0...2000 {
      dispatchGroup.enter()
      // Perform on background thread, async
      queue.async {
        Alamofire.request { response in
          dispatchGroup.leave()
          // ...
        }
      }
    }
    
    dispatchGroup.notify(queue: .main, execute: {
      print("DONE WITH ALL REQUESTS")
    })
    

    Hope it helps.