一尘不染

为什么我无法从Alamofire获得请求结果

json

我无法获取Alamofire请求的结果。因此,我创建了从json异步调用获取的数组的输出。我无法从dispatch
{…}中获取resultArray。当我添加println来调试代码。第二个出现在第一个之前。我只想要resultArray从Alamofire获取数据以显示在UIPickerView中。请帮助!!!

这是我的代码

import UIKit
import Alamofire

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource{

@IBOutlet var venuePicker : UIPickerView?

var resultOld = [String:String]() // i need it to get only value from json

var result : [String]?

let refreshControl = UIRefreshControl()

override func viewDidLoad() {

    if result == nil {
        populateVenues ({ (error, result) -> Void in
            self.result = result as? [String]
            self.venuePicker?.reloadAllComponents()
        })
    }
}

func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
    return 1
}

func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    if result != nil{
        return result!.count// Why i can't use result?.count instead of result!.count
    }
    else{
        return 0
    }
}

func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
    if result != nil{
        println(result)
        return result?[row]
    }
    else{
        return "..."
    }
}

func populateVenues(completion : (error: NSError?,result : AnyObject?) -> Void){
    Alamofire.request(.POST, "http://xxxx.xxxx.xxx").responseJSON() {
        (_, _, jsonData, error) in

        if error == nil{
            var venues = JSON(jsonData!)

            for (k, v) in venues {

                self.resultOld[k] = v.arrayValue[0].stringValue
            }

            self.result = self.resultOld.values.array

            completion(error: nil,result: self.result)
        }
        else{
            println("Error!!")
            completion(error: error!,result: nil)
        }
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

这是我在控制台上的输出

The 2st result array : []
The 1st result array : [ORIX Kobe Nyusatsu, NPS Sendai Nyusatsu, JU Gunma, KAA Kyoto, JU Ibaraki, USS Gunma, ISUZU Kobe, NAA Osaka Nyusatsu, SMAP Sapporo Nyusatsu, L-Up PKobeNyusatsu, ARAI Sendai, TAA Minami Kyushu, NPS Oyama Nyusatsu, CAA Tokyo, JU Toyama, USS Shikoku, NPS Gifu Nyusatsu, NAA Fukuoka, KCAA Yamaguchi, JU Fukuoka, LAA Kansai, JAA, TAA Kinki, USS Sapporo, JU Miyagi, USS Fukuoka, JU Tokyo]

请我真的需要知道我正在发生什么以及为什么我不能首先获得异步调用的结果。


阅读 228

收藏
2020-07-27

共1个答案

一尘不染

因此,异步调用是在另一个线程上执行的。因此,当您调用该函数时populateVenue(),该populateVenue()函数未在之前完成println("The 2st result array : \(self.resultArray)" )。如果您设置populateVenue()要关闭,则不会发生这种情况。例:

override func viewDidLoad() {

   super.viewDidLoad()

   populateVenue( { (error, result) -> Void in 
      println("The 2st result array : \(self.resultArray)" )
   })
}

func populateVenue(completion: (error: NSError?, result: AnyObject?) -> Void) {
    Alamofire.request(.POST, "http://localhost:8080/ws/automobile/global/auction/latest/venues").responseJSON() {
    (_, _, jsonData, error) in

       if error == nil {
          // do whatever you need
          // Note that result is whatever data you retrieved
          completion(nil, result)
       } else {
           println("Errror")
           completion(error!, nil)
       }
   }
}

编辑:

我仍在尝试了解您的问题,但这是我的最佳选择。请注意,我不知道resultOld的用途是什么,因此我将其删除。如果绝对需要,可以将其重新添加。我的设计是使属性成为可选属性,并将结果返回到完成块中。然后,在viewDidLoad中,您可以初始化属性数组并重新加载屏幕。

@IBOutlet var venuePicker : UIPickerView?

// Try making this optional so you can tell when the network call is completed
var result: [String]?

var error = "Error"

let refreshControl = UIRefreshControl()

override func viewDidLoad() {
    if result == nil {
       populateVenues ( { (result) -> Void in
          self.result = result
          self.venuePicker?.reloadAllComponents()
       })
    }
}

func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
    return 1
}

func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
     if result != nil {
        return result.count
     } else {
        return 0
     }
}

func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {

    return result[row]
}

func populateVenues(completion : (result : [String]?) -> Void){
    Alamofire.request(.POST, "http://localhost:8080/ws/automobile/global/auction/latest/venues").responseJSON() {
        (_, _, jsonData, error) in

        if error == nil{
            var venues = JSON(jsonData!)

            for (k, v) in venues {

                resultOld[k] = v.arrayValue[0].stringValue

            }

            result = resultOld.values.array

            completion(result: result)
        }
        else{
            println("Error!!")
            completion(result: nil)
        }
    }
}
2020-07-27