第一次单击时未显示数据

时间:2019-06-18 09:01:55

标签: ios json swift

我的应用正在解码来自PHP Web服务的一些JSON数据,但是当我第一次单击“获取”按钮时,数据未显示在标签上。

在调试中,我可以看到数据已传递到数组,但未传递到视图控制器中的标签。

您能帮我吗?

预先感谢

阿德莫

单击按钮

@IBAction func btn_ler(_ sender: Any)
    {

        //txt_matricula.text = ""
        //txt_marca.text = ""
        //txt_modelo.text = ""

        obter_dados_veiculo(matricula: input_matricula.text!)

        for veiculo in a_veiculos
        {
            txt_matricula.text = veiculo.MATRICULA
            txt_modelo.text = veiculo.MODELO
            txt_marca.text = veiculo.MARCA
        }

        //lbl_num_servicos.text = String( a_veiculos.count)
    }

用于检索JSON的函数

func obter_dados_veiculo (matricula : String)
    {
        //Variável que vai conter o URL
        let v_url = "http://arshome.hopto.org/Domingues/DEV/api_get_veiculos.php?MATRICULA=" + matricula

        let o_url = URL(string: v_url)

        URLSession.shared.dataTask(with: o_url!)
        {
            (data, response, error) in

            do
            {
                let matriculas = try JSONDecoder().decode([s_veiculo].self, from: data!)


                //for matricula in matriculas
                //{
                    //print(matricula.MATRICULA)
                a_veiculos = []
                    a_veiculos.append(contentsOf: matriculas)
                //}
            }
            catch
            {
                print("We have an error!")
                //self.txt_matricula.text = "We have an error!"
            }
            print( a_veiculos.count)
            }.resume()
    }

4 个答案:

答案 0 :(得分:1)

您必须在closure方法中添加完成obter_dados_veiculo,如下所示:

func obter_dados_veiculo (matricula : String, completion:@escaping(Bool,Error?)->())
{
    //Variável que vai conter o URL
    let v_url = "http://arshome.hopto.org/Domingues/DEV/api_get_veiculos.php?MATRICULA=" + matricula

    let o_url = URL(string: v_url)

    URLSession.shared.dataTask(with: o_url!)
    {
        (data, response, error) in

        do
        {
            let matriculas = try JSONDecoder().decode([s_veiculo].self, from: data!)


            //for matricula in matriculas
            //{
            //print(matricula.MATRICULA)
            a_veiculos = []
            a_veiculos.append(contentsOf: matriculas)
            completion(true,nil)
            //}
        }
        catch let error as NSError
        {
            print("We have an error!")
            completion(false,error)
            //self.txt_matricula.text = "We have an error!"
        }
        print( a_veiculos.count)
        }.resume()
}

并按以下方式调用它:

@IBAction func btn_ler(_ sender: Any)
{

    //txt_matricula.text = ""
    //txt_marca.text = ""
    //txt_modelo.text = ""

    obter_dados_veiculo(matricula: input_matricula.text!) { (success, error) in
        for veiculo in self.a_veiculos
        {
            txt_matricula.text = veiculo.MATRICULA
            txt_modelo.text = veiculo.MODELO
            txt_marca.text = veiculo.MARCA
        }
    }

    //lbl_num_servicos.text = String( a_veiculos.count)
}

答案 1 :(得分:1)

您的问题是您执行异步网络请求,这意味着不能保证在您将文本分配给标签时,已经收到网络响应。

    obter_dados_veiculo(matricula: input_matricula.text!)

    //RESPONSE MAY NOT BE RECEIVED

    for veiculo in a_veiculos
    {
        txt_matricula.text = veiculo.MATRICULA
        txt_modelo.text = veiculo.MODELO
        txt_marca.text = veiculo.MARCA
    }

您可以执行的选择之一是将属性观察器添加到 a_veiculos ,例如:

var a_veiculos: [s_veiculo] = [] {
    didSet {
        for veiculo in a_veiculos
          {
             txt_matricula.text = veiculo.MATRICULA
             txt_modelo.text = veiculo.MODELO
             txt_marca.text = veiculo.MARCA
          }
    }
}

答案 2 :(得分:0)

这样编写另一个方法initializeData()。

 func initializeData() {
   for veiculo in a_veiculos
    {
        txt_matricula.text = veiculo.MATRICULA
        txt_modelo.text = veiculo.MODELO
        txt_marca.text = veiculo.MARCA
    }

 }

并在初始化数组时调用此方法。

 func obter_dados_veiculo (matricula : String)
     {
    //Variável que vai conter o URL
    let v_url = "http://arshome.hopto.org/Domingues/DEV/api_get_veiculos.php?MATRICULA=" + matricula

    let o_url = URL(string: v_url)

    URLSession.shared.dataTask(with: o_url!)
    {
        (data, response, error) in

        do
        {
            let matriculas = try JSONDecoder().decode([s_veiculo].self, from: data!)


            //for matricula in matriculas
            //{
                //print(matricula.MATRICULA)
            a_veiculos = []
                a_veiculos.append(contentsOf: matriculas)
          initializeData()
            //}
        }
        catch
        {
            print("We have an error!")
            //self.txt_matricula.text = "We have an error!"
        }
        print( a_veiculos.count)
        }.resume()
}

答案 3 :(得分:0)

使用完成处理程序,以便在API调用完成时获得更新。并相应地更新UI。这是使用“完成处理程序”的方法。

@IBAction func btn_ler(_ sender: Any)
{

    obter_dados_veiculo(matricula: input_matricula.text!) {
        DispatchQueue.main.async {
            for veiculo in a_veiculos
            {
                txt_matricula.text = veiculo.MATRICULA
                txt_modelo.text = veiculo.MODELO
                txt_marca.text = veiculo.MARCA
            }
        }
    }
}

func obter_dados_veiculo (matricula : String, completionHandler: @escaping () -> Void) {
    //Variável que vai conter o URL
    let v_url = "http://arshome.hopto.org/Domingues/DEV/api_get_veiculos.php?MATRICULA=" + matricula
    let o_url = URL(string: v_url)
    URLSession.shared.dataTask(with: o_url!) {
        (data, response, error) in
        do {
            let matriculas = try JSONDecoder().decode([s_veiculo].self, from: data!)
            a_veiculos = []
            a_veiculos.append(contentsOf: matriculas)
        }
        catch {
            print("We have an error!")
            //self.txt_matricula.text = "We have an error!"
        }
        print( a_veiculos.count)
        }.resume()
}