Reputation: 305
I have a function that takes location coordinates and fetches weather data. This function is used at other places in the code.
Currently I'm using urlsession in cellForRowAt directly but dont want to repeat the code. Is there a way to call this weather function in TableViewController's cellForRowAt to update cells?
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]? {
}
}
In cellForRowAt, How to modify weather function to get values here before returning the cell, but original functionality of weather function taking completion should also stay?
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = ...
Data.weather() ** ??? **
cell.label.text = "" // value from weather
return cell
}
Upvotes: 0
Views: 865
Reputation: 2397
Triggering a network call in cellForRowAt indexPath
is a bad idea. The method is called whenever the user scrolls through the table view. This could lead to a lot of network calls.
Instead you should:
viewWillAppear
. This method is called every time the app switches to your tableViewarray
.reloadData
cellForRowAt indexPath
configure the cell with the data from the array
.Lets look at an example (it is incomplete, but should give you an idea, what to do):
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
}
}
Upvotes: 1