json - 为什么我无法从 Alamofire 获取请求结果

标签 json swift alamofire

我无法获得 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]

拜托,我真的需要知道我发生了什么,以及为什么我不能先得到异步调用的结果。

最佳答案

所以异步调用是在另一个线程上执行的。因此,当您调用函数 populateVenue() 时,populateVenue() 函数在 println("The 2st result array :\(self.结果数组)”)。如果您将 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 的用途是什么,所以我删除了它。如果你绝对需要它,你可以把它加回去。我在这里的设计是使属性可选,并在完成 block 中返回结果。然后在 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)
        }
    }
}

关于json - 为什么我无法从 Alamofire 获取请求结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28207185/

相关文章:

ios - 使用 Alamofire 从 Firebase 检索 JSON

用于播放通过套接字传输的 wav 文件的 iOS 库

ios - 这个功能对吗?调用带闭包的函数(swift - iOS)

java - 使用 Java 将 Json 对象转换为 Parquet 格式而不转换为 AVRO(不使用 Spark、Hive、Pig、Impala)

Python Pandas 从复杂字典中创建记录

javascript获取非空JSON子数组的计数

c# - 如何为具有无效值的属性使用 JSON.net 的默认值

ios - 我在尝试使用 Reachablitiy 时遇到错误

swift - Swift 中的命令模式与结构的变异方法

iphone - 如何使用 Alamofire SWIFT 在 post api 中发送 JSON