[英]RxSwift TableView - How to set numberOfRowsInSection?
[英]How to fix TableView numberOfRowsInSection returning nil?
我正在嘗試使用OpenWeatherMap API檢索5天的預測,我不知道為什么,但每次調用我的weatherCount()方法時它返回nil。
在視圖模型中,我使用print語句來驗證行數應為40.我試圖使用保護語句並強制解包,這只會導致程序崩潰。 我嘗試實現回調方法但不認為我做得正確。
WeatherViewModel
import Foundation
class WeatherViewModel {
var weatherInfo: WeatherData?
weak var delegate: WeatherDelegate?
func getWeatherData() {
let weather = "https://api.openweathermap.org/data/2.5/forecast?q=London,GB&appid=fe3e0ecae7e573d25b37542f96f66f1a"
guard let url = URL(string: weather) else {
print("Could not reach the API endpoint") // this guard is not being hit
return }
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in //data task object, completion handler(trailing closure)
DispatchQueue.main.async {
guard error == nil else { // Checking for errors in the request
print("Error retrieved was: \(error)")
return
}
guard let weatherResponse = data else { //checks we got the data from request
print("Could not retrieve data instead got \(data)")
return }
}
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
let responseData = try decoder.decode(WeatherData.self, from: data!)
DispatchQueue.main.async {
// print("Delegate method shows \(self.delegate?.didRecieve(forecast: responseData))")
self.weatherInfo = responseData
print(self.weatherInfo)
print("Number of rows in section will be : \(self.weatherInfo?.list.count ?? 1)")
}
}
catch let e as Error {
print("Error creating current weather from JSON because: \(e.localizedDescription)")
print("Error in parsing the JSON")
NSLog("Error hit when calling weather service \(e)")
}
}
task.resume()
}
func weatherCount() -> Int {
let numberOfRows = self.weatherInfo?.list.count
print("Number of rows in weatherCount : \(numberOfRows)")
return numberOfRows ?? 1
}
}
WeatherTableViewController
import UIKit
import Foundation
class WeatherTableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet var tableView: UITableView!
lazy var viewModel: WeatherViewModel = {
return WeatherViewModel()
}()
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
DispatchQueue.main.async {
self.viewModel.getWeatherData()
self.tableView.reloadData()
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 5
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//print("Number of rows in section is: \(viewModel.weatherInfo?.list.count)")
//print("Rows: \(viewModel.weatherCount())")
return viewModel.weatherCount() ?? 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let weatherCell = tableView.dequeueReusableCell(withIdentifier: "WeatherCell", for: indexPath)
weatherCell.textLabel?.text = " The current temperature is : \(viewModel.weatherInfo?.list[indexPath.row].main?.temp ?? 0)"
print(viewModel.weatherInfo?.list[indexPath.row].main?.temp)
return weatherCell
}
}
numberOfRowsInSection應該返回40但是返回nil
天氣
import Foundation
struct WeatherData: Decodable {
let cod: String
let message: Double
let cnt: Int
let list: [Info]
}
struct Info: Decodable {
let dt: Date
let main: WeatherInfo?
}
struct WeatherInfo: Decodable {
let temp: Double
let temp_min: Double
let temp_max: Double
let pressure: Double
let sea_level: Double
let grnd_level: Double
let humidity: Int
let temp_kf: Double
}
private enum CodingKeys: String, CodingKey {
case minTemp = "temp_min"
case maxTemp = "temp_max"
case seaLevel = "sea_level"
case temp
case pressure
case groundLevel = "grnd_level"
case humidity
case temp_kf
}
使用completion
處理程序從天氣數據解析中獲取通知,然后重新加載tableView
,如下所示,
func getWeatherData(_ completion: @escaping () -> Void) {
let weather = "https://api.openweathermap.org/data/2.5/forecast?q=London,GB&appid=fe3e0ecae7e573d25b37542f96f66f1a"
guard let url = URL(string: weather) else {
print("Could not reach the API endpoint") // this guard is not being hit
return }
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in //data task object, completion handler(trailing closure)
guard error == nil else { // Checking for errors in the request
print("Error retrieved was: \(error)")
return
}
guard let weatherResponse = data else { //checks we got the data from request
print("Could not retrieve data instead got \(data)")
return
}
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
let responseData = try decoder.decode(WeatherData.self, from: data!)
DispatchQueue.main.async {
// print("Delegate method shows \(self.delegate?.didRecieve(forecast: responseData))")
self.weatherInfo = responseData
completion()
}
}
catch let e as Error {
print("Error creating current weather from JSON because: \(e.localizedDescription)")
print("Error in parsing the JSON")
NSLog("Error hit when calling weather service \(e)")
}
}
task.resume()
}
將viewDidLoad
更新為,
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
self.viewModel.getWeatherData() {
self.tableView.reloadData()
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.