2017-08-09 12 views
0

私は位置座標を取り、気象データを取得する関数を持っています。この関数は、コードの他の場所で使用されます。TableViewCellをurlsessionを持つ関数で更新するには? Swift

現在、私はcellForRowAtでurlsessionを直接使用していますが、コードを繰り返す必要はありません。 TableViewControllerのcellForRowAtでこのweather関数を呼び出してセルを更新する方法はありますか?天候機能、撮影完了の

セルを返す前に、ここで値を取得するために、気象機能を変更する方法cellForRowAt、で
class Data { 
    static func weather (_ coord:String, completion: @escaping...([String?]) ->(){ 

     let url = URL(string: "https://") 

     let task = URLSession.shared.dataTask(with: url!) { data, response, error in 

     let json = processData(data) //returns [String]? 

     completion(json) 
     } 
     task.resume() 


    } 

    static func processData(_ data: Data) -> [String]? { 

    } 
} 

が、元の機能も滞在する必要がありますか?

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = ... 
    Data.weather() ** ??? ** 
    cell.label.text = "" // value from weather 
    return cell 
} 
+0

**ビューで** **ビューを更新しないでください* *。 **コントローラ**の**モデル**を更新し、**ビュー**を更新します。 – vadian

+0

tableView.reloadData()は完了後(リクエストが完全に呼び出されたとき)に使用します。 –

答えて

1

cellForRowAt indexPathでネットワークコールをトリガーすることは悪い考えです。このメソッドは、ユーザーがテーブルビューをスクロールするたびに呼び出されます。これは、多くのネットワークコールにつながる可能性があります。

代わりに、あなたがしなければならない:

  • を必要なときだけネットワーク呼び出しを行います。たとえば、viewWillAppearでそれを行うことができます。このメソッドは、アプリケーションがあなたのテーブルビューに切り替えるたびに呼び出されます
  • モデルでのネットワーク呼び出しの結果を格納します。これは、arrayのような単純なものかもしれません。
  • テーブルビューを再描画するreloadData
  • cellForRowAt indexPatharrayのデータでセルを構成します。

は(それは不完全ですが、あなたのアイデアを与える必要があり、何をすべきか)の例を見てみましょう:

class WeatherTableView: UITableView { 
    var weatherData: [String] 

    override func viewWillAppear(_ animated: Bool) { 
    loadWeatherData() 
    } 

    private func loadWeatherData() { 
    // I just set some data here directly. Replace this with your network call 
    weatherData = ["Here comes the sun", "Rainy with chance of meatballs", "It's raining cats and dogs"] 
    // Make sure the tableView is redrawn 
    tableView.reloadData() 
    } 

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "weatherDataCell") 
    cell.label.text = weatherData[indexPath.row] 
    return cell 
    } 
} 
+0

説明してくれてありがとうございます。問題の一部分は同じではないでしょうか?viewWillAppearのfor-inループを経て値を収集しても、非同期呼び出しを実行する関数で値を収集していませんか? –

+0

あなたの質問が正しく理解されているかどうかわかりません。 'viewWillAppear'でネットワーク呼び出しを行うと、ビューが画面上に表示されたときにのみ行われます。描画されると、 'viewWillAppear'は再びロードされません。これはブレークポイントを使って確認できます。 –

+0

もしあなたが私の答えが役に立つと分かったら、それを受け入れられた答えにしてください:) –

関連する問題