2017-06-15 42 views
0

我是帶有jsonserialization的webrequest,之後是for-in提取過程。整個過程大約需要5-7秒鐘的時間。 之後,我想在Viewcontroller中引用我的tableview。 函數的方案如下所示。WebRequest會話中的完成處理

public struct Container { 
    let name: String 
    let symbol: String 
    let rank: String 
} 

public var dataArray = [Container]() 


func fetchNewData() { 

    var view = ViewController() 

    // WebbRquest... 

    // Json serialization... 

    // the following list is much longer, will take a while... 
    for items in json { 
     let name = items["name"] as? AnyObject; 
     let symbol = items["symbol"] as? AnyObject; 
     let rank = items["rank"] as? AnyObject; 
     let result = Container(name: name! as! String, symbol: symbol! as! String,rank: rank! as! String) 

     dataArray.append(result) 
    } 

    // Now, after alle the work is done, i want to reload the tableview in Viewcontrller: 
    view.reload() 

    // Here i´m getting error, because nothing will be executed after return. 

} 

我如何可以調用重載函數時,WebRequest的過程完成後?因爲在返回之後,函數不再執行任何操作。 當fetchNewData()函數完成時,沒有其他函數會「知道」。 感謝您的幫助!

@IBAction func updateButton(_ sender: Any) { 

    fetchNewData() 

    } 

據菲利浦斯的建議,我不得不修改@IBAction FUNC一點點。 但現在它工作。真棒! 這裏完整的工作版本:

public struct Container { 
    let name: String 
    let symbol: String 
    let rank: String 
} 

public var dataArray = [Container]() 


func fetchNewData(completion:@escaping ([Container])->()) { 

    var view = ViewController() 

    // WebbRquest... 

    // Json serialization... 

    // the following list is much longer, will take a while... 
    for items in json { 
     let name = items["name"] as? AnyObject; 
     let symbol = items["symbol"] as? AnyObject; 
     let rank = items["rank"] as? AnyObject; 
     let result = Container(name: name! as! String, symbol: symbol! as! String,rank: rank! as! String) 

     dataArray.append(result) 
    } 

    completion(dataArray) 


} 

這是actionFunc:

@IBAction func upDateButton(_ sender: Any) { 

      let data = dataArray 

      fetchNewData() {_ in (data) 

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

} 
+0

隨着你的其他問題,這:'var view = ViewController()'不會幫助你。這會創建一個**新的** ViewController,它不在屏幕上,並且對要更新的表一無所知。什麼對象調用'fetchNewData'? (即在哪裏使用容器數組?) –

+0

謝謝,我剛剛更新了代碼。我必須糾正自己,而不是容器追加結果,它的dataArray。這個dataArray顯示在一個tableview中。 –

+0

是否有解決方案來訪問重載功能,這是(而且必須)在ViewController類? –

回答

1

這裏是一個開始。它會模糊,因爲我正在猜測我看不到的代碼,但是您可能可以將其轉換爲您自己的需要。

改變,因此,它需要一個閉包作爲參數的提取功能:

func fetchNewData(completion:([Container])->()) { 

...注意,關閉將接受數據數組時,它的調用。 之後,你有你的JSON解析一切,你再調用關閉:

dataArray.append(result) 
} 
completion(dataArray) 

「魔術師」是在你告訴fetchNewData它結束時做什麼視圖控制器。喜歡的東西:

@IBAction func updateButton(_ sender: Any) { 
    fetchNewData() {(data) 
     // Save the data where the view controller can use it 
     self.tableArray = data 

     // Main queue for UI update 
     DispatchQueue.main.async { 
      self.tableView.reloadData() 
     } 
    } 
} 

注意,封閉是寫在視圖控制器,所以self是視圖控制器。這意味着無需在獲取中創建第二個(無用的)控制器。

+0

完美的解決方案!我只需在調用fetchNewData函數之前創建一個「let data = dataArray」。 –