2

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

            }
        }
    }
}
Marco Almeida
  • 1,285
  • 3
  • 17
  • 39
  • Try to use CodyFire lib it is much better https://github.com/MihaelIsaev/CodyFire – imike Mar 15 '20 at 19:14
  • I’m not really sure if this is a bad practice. But since you have hard-coded values in your for-loop you can check ’if i == 2000’. But not sure if this is recommended. I would break this out in another method (and use as less code as possible in the viewDidLoad) and then use the ’@escaping’ block. And inside the ’DispatchQueue.main.async’ i’d return the method – Putte Mar 15 '20 at 19:54
  • I would suggest you don't create your requests this way, especially when using Alamofire 4, as Alamofire 4 has scaling issues when used like this. Instead, you should batch your requests into batches of perhaps 6 at a time and run your other requests as others complete. – Jon Shier Mar 15 '20 at 23:47

1 Answers1

2

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.

kerim.ba
  • 276
  • 1
  • 8