我有一个函数getZipCodefromURL
,它从气象数据服务中检索数据,解析json,并将信息分类到我的array
。在我的应用程序中,我有一个文本字段,一个按钮和标签设置,以便用户可以在文本字段中输入他或她的邮政编码并点击按钮,该按钮将更新标签,其中包含有关其所在区域天气的信息。
我认为我遇到的问题来自于我的功能设置方式或我调用它的方式。在我的enterButton
函数中,我想从getZipCodeinURL
检索我的填充数组,但是当我调用它时,它返回空,我无法对其进行索引。到目前为止,这就是我所拥有的:
var array: [String] = []
func getZipCodeinURL(zipCode: String) -> NSArray{
let urlPath = "http://api.openweathermap.org/data/2.5/weather?zip=\(zipCode),us&units=imperial"
let url: NSURL = NSURL(string: urlPath)!
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in
if error != nil {
// If there is an error in the web request, print it to the console
println(error.localizedDescription)
return
}
var err: NSError?
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
if err != nil {
// If there is an error parsing JSON, print it to the console
println("JSON Error \(err!.localizedDescription)")
return
}
let json = JSON(jsonResult)
var temp = json["main"]["temp"].stringValue
var humidity = json["main"]["humidity"].stringValue
var pressure = json["main"]["pressure"].stringValue
self.array = [temp, humidity, pressure]
})
task.resume()
return array
}
@IBOutlet weak var pressureLabel: UILabel!
@IBOutlet weak var humidityLabel: UILabel!
@IBOutlet weak var tempLabel: UILabel!
@IBAction func enterButton(sender: AnyObject) {
var zipCode = zipcodeText.text
var weatherArray: NSArray = getZipCodeinURL(zipCode)
var temperature: AnyObject = weatherArray[0]
}
有谁知道如何从我的函数中正确检索已填充的array
到我的enterButton
函数中?
答案 0 :(得分:1)
假设您的其余代码是正确的,您所犯的错误是对NSURLSessionDataTask.resume()
的调用是异步的。它将在进行网络呼叫时返回(在array
之前填充了您提供的完成块中的结果)。因此return array
将正确返回您在上面声明的空数组。
要解决此问题,请让getZipCodeinURL
不返回任何内容。在完成块内,调用另一个将使用该数组的函数(例如make didFinishLoadingArray
)。在self.array = ...
之后拨打此电话。然后更改enterButton
函数以启动数据检索。它看起来像这样:
var array: [String] = []
func getZipCodeinURL(zipCode: String) {
let urlPath = "http://api.openweathermap.org/data/2.5/weather?zip=\(zipCode),us&units=imperial"
let url: NSURL = NSURL(string: urlPath)!
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in
if error != nil {
// If there is an error in the web request, print it to the console
println(error.localizedDescription)
return
}
var err: NSError?
var jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSDictionary
if err != nil {
// If there is an error parsing JSON, print it to the console
println("JSON Error \(err!.localizedDescription)")
return
}
let json = JSON(jsonResult)
var temp = json["main"]["temp"].stringValue
var humidity = json["main"]["humidity"].stringValue
var pressure = json["main"]["pressure"].stringValue
self.array = [temp, humidity, pressure]
didFinishLoadingArray()
})
task.resume()
}
@IBOutlet weak var pressureLabel: UILabel!
@IBOutlet weak var humidityLabel: UILabel!
@IBOutlet weak var tempLabel: UILabel!
@IBAction func enterButton(sender: AnyObject) {
var zipCode = zipcodeText.text
getZipCodeinURL(zipCode)
}
func didFinishLoadingArray() {
var temperature: AnyObject = self.array[0]
}
如果您以这种方式更新UI,则还需要确保在主线程上执行此操作。查看如何做到这一点。
答案 1 :(得分:-1)
查看Alamofire并特别注意响应处理。
基本上,您可以进行GET
调用,并在调用有响应后告诉代码执行。 Alamofire还直接与SwiftyJSON集成。让你很容易理解你的回应.JSON。
你可以很容易地做到这样的事情。
@IBAction func enterButton(sender: AnyObject) {
getZipCodeinURL(zipCode)
}
func getZipCodeinURL(zipCode: String){
Alamofire.request(.GET, "http://api.openweathermap.org/data/2.5/weather?zip=\(zipCode),us&units=imperial")
.responseJSON { jsonResult in
debugPrint(jsonResult)
let json = JSON(jsonResult)
var temp = json["main"]["temp"].stringValue
var humidity = json["main"]["humidity"].stringValue
var pressure = json["main"]["pressure"].stringValue
var weatherArray: NSArray = [temp, humidity, pressure]
var temperature: AnyObject = temp
}
}
请告诉我这是否适合您。