如何修复TableView numberOfRowsInSection返回nil?

时间:2018-12-30 12:21:13

标签: ios swift

我正在尝试使用OpenWeatherMap API检索5天的天气预报,我不确定为什么,但是每次我调用weatherCount()方法时,它都会返回nil。

在视图模型中,我使用打印语句来验证行数应为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
}

1 个答案:

答案 0 :(得分:3)

使用<vue-good-table :columns="columns" :rows="rows"> <template slot="table-row" slot-scope="props"> <div @contextmenu.prevent="openMenu($event,props.row)" > {{props.formattedRow[props.column.field]}} </div> </template> </vue-good-table> 处理程序从天气数据解析中获取通知,然后按如下所示重新加载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