Json 为什么可以';我不能从Alamofire获得请求结果吗

Json 为什么可以';我不能从Alamofire获得请求结果吗,json,swift,alamofire,Json,Swift,Alamofire,我无法获取Alamofire请求的结果。因此,我创建了一个数组的输出,该数组是从json异步调用中获得的。我无法从调度{…}中获取结果数组。当我添加println调试代码时。第二个数组首先出现在第一个数组之前。 我想用resultArray从Alamofire获取数据并显示在UIPickerView中。请帮助 这是我的密码 import UIKit import Alamofire class ViewController: UIViewController, UIPickerViewDele

我无法获取Alamofire请求的结果。因此,我创建了一个数组的输出,该数组是从json异步调用中获得的。我无法从调度{…}中获取结果数组。当我添加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]

请告诉我,我真的需要知道发生了什么,为什么我不能首先得到异步调用的结果。

所以异步调用是在另一个线程上执行的。因此,当您调用函数
populateVenue()
时,
populateVenue()
函数在
println(“2st结果数组:\(self.resultArray)”
之前没有完成。如果将
populateVenue()
设置为关闭,则不会发生这种情况。 例如:

编辑:

我仍在努力理解你的问题,但这是我最好的办法。注意,我不知道resulttell的目的是什么,所以我删除了它。如果你确实需要它,你可以把它加回去。我在这里的设计是使属性成为可选的,并在完成块中返回结果。然后在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)
        }
    }
}

异步调用需要时间。在PopulateVince函数中设置完成块,并将2st结果数组放入完成块。这样,它只会在完全填充完成后打印。您可以建议我如何首先获取数据。请,任何代码建议都将不胜感激。谢谢uOk。我发布了一个答案,其中包含我所说的完成块的基本代码。@Rob>重新加载数据,没有成功@ad121,谢谢。如果你不介意,你能给我一个解决方案吗。现在我在viewDidLoad中得到了第二个数组,但它只在PopulateVinces{}中起作用。我仍然无法得到resultArray,有什么帮助吗?我已经更新了代码现在我在viewDidLoad中得到了第二个数组,但它只在PopulateVinces{}中起作用。我仍然无法得到resultArray,有什么帮助吗?我很抱歉,我忘了在完成块中指定变量的类型。我更新了我的答案。而且,我不知道你的第二条评论是什么意思。您能澄清一下吗?如您所见,调用函数populateVince时,结果[]不能在闭包外使用。因此,为了在UIPickerView中显示数据,必须返回UIPickerView的委托和数据源方法。那么,我该如何解决这个问题呢?谢谢您我在计算结果时更新了代码,你会看到它发生在我身上。我是异步编程新手。请帮助我
@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)
        }
    }
}