从API(JSON格式)中提取数据不会将函数调用以外的数据保存到
我想从JSON格式的API中获取给定时间段内的温度数组。我能够通过完成处理程序检索数组,但我无法将其保存到函数调用之外的另一个变量(使用完成处理程序的变量)。这是我的代码。请参阅评论区域。从API(JSON格式)中提取数据不会将函数调用以外的数据保存到
class WeatherGetter {
func getWeather(_ zip: String, startdate: String, enddate: String, completion: @escaping (([[Double]]) -> Void)) {
// This is a pretty simple networking task, so the shared session will do.
let session = URLSession.shared
let string = "api address"
let url = URL(string: string)
var weatherRequestURL = URLRequest(url:url! as URL)
weatherRequestURL.httpMethod = "GET"
// The data task retrieves the data.
let dataTask = session.dataTask(with: weatherRequestURL) {
(data, response, error) -> Void in
if let error = error {
// Case 1: Error
// We got some kind of error while trying to get data from the server.
print("Error:\n\(error)")
}
else {
// Case 2: Success
// We got a response from the server!
do {
var temps = [Double]()
var winds = [Double]()
let weather = try JSON(data: data!)
let conditions1 = weather["data"]
let conditions2 = conditions1["weather"]
let count = conditions2.count
for i in 0...count-1 {
let conditions3 = conditions2[i]
let conditions4 = conditions3["hourly"]
let count2 = conditions4.count
for j in 0...count2-1 {
let conditions5 = conditions4[j]
let tempF = conditions5["tempF"].doubleValue
let windspeed = conditions5["windspeedKmph"].doubleValue
temps.append(tempF)
winds.append(windspeed)
}
}
completion([temps, winds])
}
catch let jsonError as NSError {
// An error occurred while trying to convert the data into a Swift dictionary.
print("JSON error description: \(jsonError.description)")
}
}
}
// The data task is set up...launch it!
dataTask.resume()
}
}
I am calling this method from my view controller class. Here is the code.
override func viewDidLoad() {
super.viewDidLoad()
let weather = WeatherGetter()
weather.getWeather("13323", startdate: "2016-10-01", enddate: "2017-04-30") { (weatherhandler: [[Double]]) in
//It prints out the correct array here
print(weatherhandler[0])
weatherData = weatherhandler[0]
}
//Here it prints out an empty array
print(weatherData)
}
的问题是,API需要一些时间来恢复数据,当数据返回“完成监听器”之称,并它进入“getWeather”方法实现中,在那里它打印数组的数据。但是,当您的外部打印方法被调用时,API尚未返回数据。所以它显示空阵列。如果您尝试在某个时间后打印数据表单“weatherData”对象,它将起作用。
我可以建议你,最好的办法是更新这样的“的GetWeather”方法实现内部与数据的UI:
override func viewDidLoad() {
super.viewDidLoad()
let weather = WeatherGetter()
weather.getWeather("13323", startdate: "2016-10-01", enddate: "2017-04-30") { (weatherhandler: [[Double]]) in
//It prints out the correct array here
print(weatherhandler[0])
weatherData = weatherhandler[0]
// Update your UI here.
}
//Here it prints out an empty array
print(weatherData)
}
这是不是一个错误,当你的controller
得到加载阵列仍然是空的,因为你的getWeather
还在做它的事(指访问API,解码JSON)当它完成了callback
将有data
返回到您的控制器。
例如,如果你使用的是的tableView,你将有reloadData()
刷新UI,分配数据weatherData
后,或者你可以放置一个property Observer
,你宣布你weatherData
财产。
var weatherData:[Double]? = nil {
didSet {
guard let data = weatherData else { return }
// now you could do soemthing with the data, to populate your UI
}
}
现在数据被分配到wheaterData
后,didSet
将被调用。
希望帮助,并且还您jsonParsing逻辑放到一个`结构:)
我可以打印此声明中的数组,但仍无法将其指定到一个全局变量。对不起。我是新来的。 –
更新你的用户界面是什么意思?对不起。我是iOS编程新手。 –
更新UI意味着您是否想要将数据设置为您的视图。如果您使用的数据显示在一些标签上,然后设置文本,但如果您将数据设置为Tablview,然后调用: yourTableView.reloadData() –
哦,我明白了。这有很大帮助。我基本上只是试图获取已完成处理程序返回的数组,并将其保存到一个全局变量,我可以稍后在我的代码的其他部分中使用它。你如何建议我实现这一目标? –