2015-10-06 6 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] 
} 

При обновлении пользовательского интерфейса таким образом, вы также должны убедиться, что вы делаете это в основном потоке. Посмотрите, как это сделать.

+0

Как я могу получить 'temp' в моей функции enterButton таким образом? – videoperson

-1

Отъезд Alamofire и посмотрите конкретно на ответную обработку.

По существу, вы можете сделать код звонка и сообщить код, чтобы выполнить его, как только этот звонок получил ответ. 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 
     } 

} 

Дайте мне знать, если это сработает для вас.

+0

Я не вижу, где ваша функция возвращает массив – Lamar

+0

My Bad, забыл удалить часть кода, которую я скопировал и вставил. Отредактированный ответ для размещения. Но по существу вы хотите установить переменные после того, как вы ответили на ваш звонок. Потому что требуется время для отправки вызова на веб-сервер и получения ответа. – haveapk

Смежные вопросы