我试图从swift 3中的闭包中提取一个数组,它不适合我。我在WeatherGetter类中有我的JSON解析器,我在viewcontroller.swift视图中调用它如何将weather_data数组分配给一些外部变量?
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 = "Insert 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!)
//print(weather)
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.updateValue(tempF, forKey: "\(date)//\(j)")
temps.append(tempF)
winds.append(windspeed)
}
}
//print(temps)
//print(winds)
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()
}
}
override func viewDidLoad() {
super.viewDidLoad()
let weather = WeatherGetter()
weather.getWeather("13323", startdate: "2016-10-01", enddate: "2017-04-30"){(weather_data) -> Void in
print(weather_data[1])
}
//Do your stuff with isResponse variable.
}
答案 0 :(得分:0)
您可以将它分配给类属性:
var weatherData: [[Double]]()
override func viewDidLoad() {
super.viewDidLoad()
let weather = WeatherGetter()
weather.getWeather("13323", startdate: "2016-10-01", enddate: "2017-04-30"){(weather_data) -> Void in
self.weatherData = weather_data
// reload or display data
}
}
您需要记住网络请求需要一些时间,所以这就是为什么一旦您知道收到响应就会调用reloadData之类的东西。
比如说,网络响应需要100毫秒才能响应。到数据响应时,viewDidLoad中的所有代码很可能都会完全完成。因此,您需要在收到数据时对其进行响应。如果您的移动信号不良,可能需要更长时间。
这就是你使用回调/闭包的原因。它们在操作完成时被调用
<强>更新强>
getWeather中的代码为我显示了多个错误,不允许我按原样运行它。
我设法通过略微修改代码和评论来获得天气API的响应。这里的主要问题是您没有将JSON数据转换为特定类型。
// The data task retrieves the data.
let dataTask = session.dataTask(with: weatherRequestURL) {
(data, response, error) -> Void in
guard error == nil, let data = data else {
print("ERROR")
return
}
// Case 2: Success
// We got a response from the server!
do {
var temps = [Double]()
var winds = [Double]()
if let weather = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String:AnyObject] {
if let conditions1 = weather["data"] as? [String:AnyObject] {
print(conditions1)
}
}
} catch let jsonError {
// An error occurred while trying to convert the data into a Swift dictionary.
print("JSON error description: \(jsonError)")
}
}
dataTask.resume()
在上面的代码中看到我如何在投射他们的类型时可选地解包值。这是您在整个代码中需要做的事情,并检查您在整个过程中的每一步都获得正确的数据。不幸的是,API响应对我来说太大了。
iOS Networking with Swift - 这是一个我强烈推荐的免费课程。这就是我学习iOS网络的方式。
答案 1 :(得分:0)
如@Scriptable所述,响应处理需要一段时间,因为它是异步的。您可以做的是添加OperationQueue.main.addOperation
以将当前进程分配给主队列。这将优先处理您的网络响应。您也可以将reloadData
放在此部分中。
var weatherData: [Double]()
override func viewDidLoad() {
super.viewDidLoad()
let weather = WeatherGetter()
OperationQueue.main.addOperation {
weather.getWeather("13323", startdate: "2016-10-01", enddate: "2017-04-30"){(weather_data) -> Void in
print(weather_data[1])
// reloadData()
}
}
}