簡體   English   中英

如何修復TableView numberOfRowsInSection返回nil?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM