【发布时间】:2018-12-30 12:21:13
【问题描述】:
我正在尝试使用 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
}
【问题讨论】:
-
欢迎来到 StackOverflow!考虑到
weatherCount()调用weatherInfo?.list.count,我的猜测是关于WeatherData的设置方式,或者数据如何映射到它。您能否添加WeatherData进行澄清? -
当然是刚刚添加的,这里还是不知道怎么格式化抱歉!