避免同时在viewDidLoad中使用Swift调用方法,并避免“索引超出范围”

时间:2018-07-07 17:43:13

标签: ios swift nsurlsession

你能帮我一下吗?我想知道如何在另一个函数结束后调用swift函数,我认为它是同时调用两个函数。这是我的viewDidLoad:

    override func viewDidLoad() { 
      super.viewDidLoad() 

        downloadJsonEscuelas(id_responsable: "5")
        downloadJsonAnuncios(id_escuela:("\arrayEscuelas[0].id_escuela!)"))    
}

第一个函数“ downloadJsonEscuelas”用数据填充数组“ arrayEscuelas”,第二个函数接收数据作为参数:

下载JsonEscuelas:

func downloadJsonEscuelas(id_responsable: String) {  

        guard let downloadURL = URL(string: Constantes.URLbase+"json/getescuelas.php?id="+id_responsable) else { return }
        URLSession.shared.dataTask(with: downloadURL) { data, urlResponse,
            error in
            guard let data = data, error == nil, urlResponse != nil else {
                print("Something went wrong")
                return
            }
            print("Escuelas downloaded")

            do
            {

                let downloadedEscuelas = try JSONDecoder().decode([Escuelas].self, from: data)
                self.arrayEscuelas = downloadedEscuelas


                DispatchQueue.main.async {


                    print("id escuela actual:"+self.idEscuelaActual!+":)")
                    self.escuelaTextBox.text = self.arrayEscuelas[0].escuela!
                    self.idEscuelaActual = "\(self.arrayEscuelas[0].id_escuela!)" as String

                }
            } catch let jsonErr {
                print("Error: ", jsonErr)
            }
            }.resume() 
    }

downloadJsonAnuncios:

func downloadJsonAnuncios(id_escuela: String) {

        guard let downloadURL = URL(string: Constantes.URLbase+"json/getanuncios.php?id="+id_escuela) else { return }
        URLSession.shared.dataTask(with: downloadURL) { data, urlResponse,
            error in
            guard let data = data, error == nil, urlResponse != nil else {
                print("Something went wrong")
                return
            }
            print("downloaded")

            do
            {

                let downloadedAnuncios = try JSONDecoder().decode([Anuncios].self, from: data)
                self.arrayAnuncios = downloadedAnuncios

                print(self.arrayAnuncios[0].titulo!)   

                DispatchQueue.main.async {
                    self.tableView.reloadData()

                }
            } catch let jsonErr {
                print("Error: ", jsonErr)
            }
            }.resume()
    }

我认为它会同时调用两个函数,因此不会在第一个函数中填充数组。当我以纯数字形式传递参数时,一切顺利,例如:

downloadJsonAnuncios(id_escuela: "2")  

希望您能在这里为我提供帮助,非常感谢。

3 个答案:

答案 0 :(得分:0)

在第一个通话(downloadJsonAnuncios(id_escuela:("\arrayEscuelas[0].id_escuela!)")))的完成中插入第二个通话(此downloadJsonEscuelas(id_responsable: "5")

func downloadJsonEscuelas(id_responsable: String) {  

        guard let downloadURL = URL(string: Constantes.URLbase+"json/getescuelas.php?id="+id_responsable) else { return }
        URLSession.shared.dataTask(with: downloadURL) { data, urlResponse,
            error in
            guard let data = data, error == nil, urlResponse != nil else {
                print("Something went wrong")
                return
            }
            print("Escuelas downloaded")

            do
            {

                let downloadedEscuelas = try JSONDecoder().decode([Escuelas].self, from: data)
                self.arrayEscuelas = downloadedEscuelas


                DispatchQueue.main.async {


                    print("id escuela actual:"+self.idEscuelaActual!+":)")
                    self.escuelaTextBox.text = self.arrayEscuelas[0].escuela!
                    self.idEscuelaActual = "\(self.arrayEscuelas[0].id_escuela!)" as String 



                }

                 // here  
                 downloadJsonAnuncios(id_escuela:("\arrayEscuelas[0].id_escuela!)"))

            } catch let jsonErr {
                print("Error: ", jsonErr)
            }
            }.resume() 
    }

答案 1 :(得分:0)

为什么在第一个关闭时不调用第二个

do {
    let downloadedEscuelas = try JSONDecoder().decode([Escuelas].self, from: data)
    self.arrayEscuelas = downloadedEscuelas

    DispatchQueue.main.async {
        print("id escuela actual:"+self.idEscuelaActual!+":)")
        self.escuelaTextBox.text = self.arrayEscuelas[0].escuela!
        self.idEscuelaActual = "\(self.arrayEscuelas[0].id_escuela!)" as String
    }
    downloadJsonAnuncios(id_escuela:("\arrayEscuelas[0].id_escuela!)")) 
} catch let jsonErr {
     print("Error: ", jsonErr)
}
}.resume()

答案 2 :(得分:0)

默认情况下,viewDidLoad中的代码在UIThread上同步运行。 您的API调用在单独的线程上运行,并允许您的其他方法在完成之前执行。 您可能应该在方法中使用完成处理程序,以便仅在api调用完成后才调用第二个方法。

有关实现CompletionHandler

的信息,请参见此答案