为啥我无法从 Alamofire 获取请求结果

Posted

技术标签:

【中文标题】为啥我无法从 Alamofire 获取请求结果【英文标题】:Why can't I get the request result form Alamofire为什么我无法从 Alamofire 获取请求结果 【发布时间】:2015-01-29 04:46:52 【问题描述】:

我无法获得 Alamofire 请求的结果。因此,我创建了从 json 异步调用获得的数组的输出。我无法从调度 ... 中获取 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]

我真的需要知道发生在我身上的事情以及为什么我不能先得到异步调用的结果。

【问题讨论】:

异步调用需要时间。在您的 populateVenue 函数中设置一个完成块,并将第二个结果数组放入完成块中。这样它只会在完整的 populateVenue 完成后打印 你能建议我如何首先获取数据吗?请提供任何代码建议。谢谢你 好的,我用完成块的基本代码发布了一个答案。 @Rob>重新加载数据,没有成功。 @ad121,谢谢。如果你不介意,你能给我一个解决方案吗? 现在我在 viewDidLoad 中得到了第二个数组,但它只能在 populateVenues 中工作。我仍然无法得到 resultArray,任何帮助?我已经更新了代码 【参考方案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)
        
    

【讨论】:

现在我在 viewDidLoad 中得到了第二个数组,但它只能在 populateVenues 中工作。我仍然无法得到 resultArray,任何帮助_? 非常抱歉,我忘记在完成块中指定变量的类型。我更新了我的答案。 另外,我不知道您的第二条评论是什么意思。你能澄清一下吗? 如你所见,调用函数populateVenue时result[]不能在闭包外使用。所以,为了在UIPickerView中显示数据,必须返回UIPickerView的delegate和datasource方法。那么,我该如何解决呢?谢谢 我在计算结果时更新了代码,你会看到它发生在我身上。我是异步编程的新手。请帮助

以上是关于为啥我无法从 Alamofire 获取请求结果的主要内容,如果未能解决你的问题,请参考以下文章

为啥请求 Alamofire 失败?

Swift - 无法获取 Alamofire.request

如何在 Alamofire 获取请求中调用包含变量或常量的结构到字典中

如何从方法返回 alamofire Http 请求的结果?

Alamofire 多个请求

为啥我无法从 ajax 发布请求中获取操作