-1

I need to download some content from API when users login for the first time at my app and show them I'm doing that. I do this at my MainViewController:

override func viewDidAppear(_ animated: Bool) {
        let alert = UIAlertController(title: nil, message: "Wait please...", preferredStyle: .alert)

        let loadingIndicator = UIActivityIndicatorView(frame: CGRect(x: 10, y: 5, width: 50, height: 50))
        loadingIndicator.hidesWhenStopped = true
        loadingIndicator.style = UIActivityIndicatorView.Style.gray
        loadingIndicator.startAnimating();

        alert.view.addSubview(loadingIndicator)
        present(alert, animated: true, completion: nil)

        let parceiroId = self.defaults.getParceiroId()
        if !self.defaults.getDownloadInicialTipoEntrega() {
            TipoEntregaAPI().loadTiposEntrega(parceiroId){ (dados) in
                if dados != nil {
                    for tipoEntrega in dados!{
                        // Do some stuff, no errors
                    }
                }
            }
        }

        if !self.defaults.getDownloadInicialPedido() {
            PedidoAPI().loadOrders(parceiroId){ (dados) in
                if dados != nil {
                    for pedidos in dados!{
                        // Do some stuff, no errors
                    }
                }
            }
        }
        self.dismiss(animated: false, completion: { () in print("Done") })
    }

The problem is that my alert with the loading never gets dismissed. It never prints "Done". Can anyone help me please?

I dont know if it is useful, but I always get this warning:

Warning: Attempt to dismiss from view controller <MyApp.MainViewController: 0x0000000> while a presentation or dismiss is in progress!
asr
  • 139
  • 3
  • 11

2 Answers2

2

The problem is exactly what the error says. Your presentation call isn't completed at the moment you're calling self.dismiss(...). For further explanation, you're calling present(alert, animated: true, completion: nil) with animated: true parameter so it's not going to finish the presentation instantly. On the other hand, you are calling self.dismiss(animated: false, completion: { () in print("Done") }) on the same thread in the relatively short instruction block, so it gets executed before the iOS finishes the animated presentation of the dialog and that's why you get the error.

But furthermore, before actually fixing the issue you should ask yourself do you really want to dismiss the dialog as soon as it's presented. Judging from the code you posted, I'd assume you want it to be dismissed after either or both of the API calls are finished. If that's the case you need to move the dismiss method call within the completion block (closures) of your API calls.

nstosic
  • 2,584
  • 1
  • 17
  • 21
  • 1
    And when you move the call to `dismiss` into the completion block, make you call it on the main queue. – rmaddy Dec 10 '18 at 17:45
  • I tried to find a solution for this warning, but it was everything in Objective C and the ones I could understand weren't like my problem. Until I searched for closure on my task I could fix it. I added a comment on my post with the solution. Thanks – asr Dec 10 '18 at 19:52
0

Solution for me (Working fine and printing "Done"):

override func viewDidAppear(_ animated: Bool) {
        if !self.defaults.getDownloadInicialTipoEntrega() || !self.defaults.getDownloadInicialPedido() || !self.defaults.getDownloadInicialVitrine() {
            Functions.showAlertWaiting("Wait please...", self)
        }

        loadDeliveryTypesNOrders { (completed) in
            if completed {
                self.dismiss(animated: false, completion: { () in print("Done") })
            }
        }
    }

func loadDeliveryTypesNOrders (completion: @escaping (Bool) -> ()) {
        let parceiroId = self.defaults.getParceiroId()
        if !self.defaults.getDownloadInicialTipoEntrega() {
            TipoEntregaAPI().loadTiposEntrega(parceiroId){ (dados) in
                if dados != nil {
                    for tipoEntrega in dados!{
                        // Do some stuff, no errors
                    }
                }
            }
        }

        if !self.defaults.getDownloadInicialPedido() {
            PedidoAPI().loadOrders(parceiroId){ (dados) in
                if dados != nil {
                    for pedidos in dados!{
                        // Do some stuff, no errors
                    }
                }
            }
        }
        completion(true)
}
asr
  • 139
  • 3
  • 11