I can't get the result of Alamofire request.So,I created ouput of an array that I got from json async call.I can't get the resultArray out of dispatch {...}.When I add println to debug the code.The second one appear first before the first one. All i want to resultArray to get the data from Alamofire to display in UIPickerView.Please Help!!!
Here is my code
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.
}
}
Here is my output at console
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]
Please i really need to know what is happening to me and why i can't get the result of async call first.
So asynchronous calls are executed on another thread. Thus, when you call the function populateVenue()
, the populateVenue()
function is not completing before the println("The 2st result array : \(self.resultArray)" )
. If you set up your populateVenue()
to have a closure, this won't happen.
Example:
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)
}
}
}
Edit:
I am still trying to understand your problem, but this is my best shot. Note that I have no idea what the purpose of resultOld is so I removed it. If you absolutely need it you can add it back in. My design here is to make the properties optional, and return the result in the completion block. Then in viewDidLoad, you can initialize the property array and reload your screen.
@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)
}
}
}