2015-10-06 53 views
0

我有一个函数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

您需要针对互联网通话研究异步呼叫。 – zaph

回答

1

假设你的代码的其余部分是正确的,你可以将这个错误是在调用NSURLSessionDataTask.resume()是异步的。当网络呼叫正在进行时(array已在您提供的完成模块中填充结果之前)它将返回。因此return array将正确返回上面声明的空数组。

要纠正这一点,请让您的getZipCodeinURL不返回任何内容。在完成块内,调用另一个函数(例如,制作一个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,你还需要确保你在主线程上执行此操作。看看如何做到这一点。

+0

我该如何解决以这种方式检索enterButton函数中的'temp'? – videoperson

-1

检出Alamofire并专门查看响应处理。

基本上你可以做一个GET打电话,告诉代码得到执行,一旦呼叫已经有了反应。 Alamofire也直接与SwiftyJSON集成。使你的responseJSON非常容易。

你可以很容易地做这样的事情。

@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 
     } 

} 

让我知道这是否适合你。

+0

我没有看到你的函数返回数组 – Lamar

+0

我的坏,忘记删除我复制和粘贴的一些代码。编辑的答案,以适应。但基本上你想要在你有回应你的电话后设置你的变量。因为将呼叫发送到Web服务器并获得响应需要时间。 – haveapk