Swift 3,如何先解析并在下一个 TableViewController 上显示

Posted

技术标签:

【中文标题】Swift 3,如何先解析并在下一个 TableViewController 上显示【英文标题】:Swift 3, how to parse first and show it on next TableViewController 【发布时间】:2018-02-21 21:02:11 【问题描述】:

我对开发 ios 应用程序非常陌生。因此,如果我的编码没有接近最佳或写得好,我也提前道歉......

我正在尝试创建一个相当简单的应用程序,仅用于显示检索和显示数据,但我遇到了一个问题,我在过去几天试图解决它,但我需要帮助...... 所以应用程序的整个功能是这样的:打开时(显示带有文本字段和按钮的视图控制器),用户应该输入用户名和按钮。按下按钮后,应用程序应按下一个顺序执行 2 件事:

    将某个URL地址与输入的用户名结合起来,检索数据 (什么样的数据,取决于给定的用户名 - 我举了几个例子 在该帖子的底部)并将它们传递给下一个 表视图控制器 显示 tableviewcontroller 并显示解析的数据。

但是,这并没有发生,我注意到的是,我的应用程序首先打开了新的 tableviewconotrller,并且在 tableviewcontroller 打开后,它解析数据,这导致我的表没有数据(但我可以看到数据已经解析,使用 print())

我正在使用 Swift 3。

带有文本字段和“登录”按钮的视图控制器:

import UIKit

class ViewController: UIViewController 
   var zavodi = [[String]]()
   @IBOutlet weak var uporabnik: UITextField!

@IBAction func vstop(_ sender: Any) 

  self.parse  (completed) in
     if (completed)
        let zavodiView = self.storyboard?.instantiateViewController(withIdentifier: "zavodiController") as! ZavodiController
        zavodiView.niz = self.uporabnik.text!
        zavodiView.zavodi = self.zavodi
        self.navigationController?.pushViewController(zavodiView, animated: true)

        
     
  


   override func viewDidLoad() 
      super.viewDidLoad()
      self.title="Vstop"
   


     func parse( completion: @escaping (_ completed: Bool)-> () )
      let uporabnikIme = uporabnik.text!
      //parsing
      let shramba = UserDefaults.standard

      let zavodiUrl = "https://oaza.rrc.si/eZaporiMobi/kapStSta/read?pUporabniskoIme="+uporabnikIme;
      var zavodiRequest = URLRequest(url: URL(string: zavodiUrl)!)
      zavodiRequest.httpMethod = "GET"

      let configuration = URLSessionConfiguration.default
      let session = URLSession(configuration: configuration, delegate: nil, delegateQueue: OperationQueue.main)

      let task = session.dataTask(with: zavodiRequest)  (data, response, error) in
         if (error != nil) 
            print("Error")
         
         else 
            var zavodiTemp = [Zavod]()
            do 
               let fetchedData = try JSONSerialization.jsonObject(with: data!) as! NSArray
               //print(fetchedData)

               zavodiTemp.removeAll()

               for najdenZavod in fetchedData 

                  let vsakZavod = najdenZavod as! [String : Any]

                  let zavodId = vsakZavod["zaiId"] as! Int
                  let naziv = vsakZavod["kratekNaziv"] as! String
                  let ureditev = vsakZavod["ureditev"] as! Int
                  let zasedenost = vsakZavod["zasedenost"] as! String
                  let kapaciteta = vsakZavod["kapaciteta"] as! Int
                  let stStanje = vsakZavod["stStanje"] as! Int
                  let naBegu = vsakZavod["naBegu"] as! Int
                  let prekinitev = vsakZavod["prekinitev"] as! Int


                  zavodiTemp.append(Zavod(zavodId: zavodId, naziv: naziv, ureditev: ureditev, zasedenost: zasedenost,kapaciteta: kapaciteta, stStanje: stStanje, naBegu: naBegu, prekinitev: prekinitev))
               
               zavodiTemp = zavodiTemp.sorted(by: $0.ureditev < $1.ureditev)

               self.zavodi.removeAll()
               for e in zavodiTemp 
                  var temp = [String]()
                  temp.append(String(e.zavodId))    //0
                  temp.append(e.naziv)              //1
                  temp.append(String(e.ureditev))   //2
                  temp.append(e.zasedenost)         //3
                  temp.append(String(e.kapaciteta)) //4
                  temp.append(String(e.stStanje))   //5
                  temp.append(String(e.naBegu))     //6
                  temp.append(String(e.prekinitev)) //7
                  self.zavodi.append(temp)
               

               let steviloZavodov = self.zavodi.count

               shramba.set(self.zavodi, forKey:"zavodi")
               shramba.set(steviloZavodov, forKey:"steviloZavodov")

               var s = [[String]]()
               s = shramba.array(forKey: "zavodi") as! [[String]]
               for e in s
                  print(e[2]+" "+e[1])
               
            
            catch 
               print()
            
          
         
         task.resume()
  completion(true)



   override func didReceiveMemoryWarning() 
      super.didReceiveMemoryWarning()
   


   class Zavod 
      var zavodId : Int
      var naziv : String
      var ureditev : Int
      var zasedenost : String
      var kapaciteta : Int
      var stStanje : Int
      var naBegu : Int
      var prekinitev : Int

      init(zavodId : Int, naziv : String, ureditev : Int, zasedenost : String, kapaciteta : Int, stStanje : Int, naBegu : Int, prekinitev : Int) 
         self.zavodId = zavodId
         self.naziv = naziv
         self.ureditev = ureditev
         self.zasedenost = zasedenost
         self.kapaciteta = kapaciteta
         self.stStanje = stStanje
         self.naBegu = naBegu
         self.prekinitev = prekinitev
      

   


TableViewController 解析后的数据应该显示在哪里: 导入 UIKit

class ZavodiController: UITableViewController 
   var niz = ""
   var zavodi = [[String]]()

    override func viewDidLoad() 
      super.viewDidLoad()
      print(niz)
      

    override func didReceiveMemoryWarning() 
        super.didReceiveMemoryWarning()

    

    override func numberOfSections(in tableView: UITableView) -> Int 
        return 1
    

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
      print("število zavodov"+String(self.zavodi.count))
        return self.zavodi.count
    

   override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
      let cell = tableView.dequeueReusableCell(withIdentifier: "zavodCelica", for: indexPath) as! ZavodCelica

      cell.nazivZavoda.text = self.zavodi[indexPath.row][1]
      cell.kapaciteta.text = self.zavodi[indexPath.row][4]
      cell.zasedenost.text = self.zavodi[indexPath.row][3]
      cell.stStanje.text = self.zavodi[indexPath.row][5]
      cell.naBegu.text = self.zavodi[indexPath.row][6]
      cell.prekinitev.text = self.zavodi[indexPath.row][7]



      return cell
   



我也尝试使用 UserDefaults,但似乎 tableviewcontroller 只是在实际解析完成之前被加载。

对于用户名,您可以使用: -“manj”,返回 1 条记录 -"mref",返回 3 条记录 -"mmli",返回 14 条记录

我非常感谢任何帮助。

【问题讨论】:

我没有阅读代码,但您是否尝试在解析数据后重新加载表格? 感谢您的提示,将查看并尝试一下。 【参考方案1】:

有很多方法可以实现这一点。重新加载表也是一个修复。但要非常准确地处理数据,您应该等待功能完成后再移动到下一个屏幕。看代码

func parse()( completion: @escaping (_ completed: Bool)-> () )


// parse logic goes in here
// after the processing finishes return true like following

  completion(true) // you can also have logic to return failures.


这将被称为

self.parse  (completed) in

  if (completed)
       let zavodiView = storyboard?.instantiateViewController(withIdentifier: "zavodiController") as! ZavodiController
       zavodiView.niz = uporabnik.text!
       zavodiView.zavodi = self.zavodi
       navigationController?.pushViewController(zavodiView, animated: true)
  


【讨论】:

我试过了(我编辑了有问题的源代码,这样你就可以看到)通过对 ViewController 进行这些更改......但它仍然有延迟,控制器之间的转换在所有数据之前执行被解析... 我在您的代码中发现了问题。 completion(true) 应该在您完成其主体内的任务之后进行。您已将其放置在 task.resume() 之后将其移动到 for 循环之后 -> for e in s dropbox.com/s/nqmjfxzn0jf9izx/… 非常感谢!!它有效,我真的很感谢你的帮助。再次感谢您。【参考方案2】:

Afetr 将数据附加到表数组添加此

  DispatchQueue.main.async 
    self.tableview.reloadData()
  

【讨论】:

对不起,但我不明白如何在第一个控制器中解析数据并在第二个控制器中显示数据的情况下使用它......或者我应该在那些数据所在的同一个控制器中解析它们或显示? 如果这个类提供一个补全并在其中重新加载表,您可以将它们解析出来

以上是关于Swift 3,如何先解析并在下一个 TableViewController 上显示的主要内容,如果未能解决你的问题,请参考以下文章

数据 > JSON - Swift3 - 转换和解析

在 iOS 中使用 Swift 保存 PDF 文件并显示它们

如何将字典存储到我的解析仪表板中并从中提取数据(Swift 3)

where 子句是先运行,然后是解析函数,或者具体是如何在下面的查询中执行的?

Swift 3 解析 JSON 嵌套问题

Swift 3:NSArray 元素无法匹配 Swift Array 元素类型