Reputation: 5096
My Current View Controller is like this
import UIKit
import Alamofire
class ViewController: UIViewController , UIPickerViewDelegate, UIPickerViewDataSource{
@IBOutlet var venuePicker : UIPickerView?
var result = [String:String]()
var resultArray = [String]()
override func viewDidLoad() {
self.venuePicker?.delegate = self
Alamofire.request(.POST, "http://example.com/xxx/xx/xx").responseJSON() {
(request, response, jsonData, error) in
var venues = JSON(jsonData!)
let d = venues.dictionaryValue
for (k, v) in venues {
self.result[k] = v.arrayValue[0].stringValue
}
self.resultArray = self.result.values.array
self.venuePicker?.reloadAllComponents()
}
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return resultArray.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return resultArray[row]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I don't know how to show value to UIPickerView from my json dictionary.i don't want key to show at UIPickerView.I am now stuck at "?????" statement.
This is my output for result
[C2517: ORIX Kobe Nyusatsu, C2510: NPS Sendai Nyusatsu, C2033: JU Gunma, C2053: KAA Kyoto, C2035: JU Ibaraki, C2077: USS Gunma, C2024: ISUZU Kobe, C2505: NAA Osaka Nyusatsu, C2529: SMAP Sapporo Nyusatsu, C2502: L-Up PKobeNyusatsu, C2005: ARAI Sendai, C2072: TAA Minami Kyushu]
Please help!!!
Upvotes: 3
Views: 5182
Reputation: 16770
Alamofire is totally async. It means that the block code will be executed when the data is ready. By then, the PickerView is already loaded, with an empty Array. That's the reason why the PickerView is empty. So in order to display the data we want, we need to force the PickerView to reload:
override func viewDidLoad() {
self.venuePicker?.delegate = self // This should be outside the block, my bad.
//...
Alamofire.request(...) {in
//...
venuePicker?.reloadAllComponents() // hopefully this will work
}
If you're not familliar with the concept of async programming, you can also choose to use sync way. Using this code I wrote https://github.com/skyline75489/swift-playground/blob/master/swift-playground%2FRequests.swift, we can easily send sync requests.
if let jsonData = Requests.get("YOUR_URL") {
let venues = JSON(jsonData)
//...
}
The reason why we have async is sometimes the data can be big and using sync way will cause the viewDidLoad
to take forever to load. That's awful for user experience. However, if the data is small. Sync way can finish the task fast enough that users won't feel it. It's totally OK to use sync ways.
Upvotes: 0
Reputation: 24572
If you wanted to show data to a picker view, use declare 2 arrays as properties instead.
var resultKeys = [String]()
var resultValues = [String]()
Inside your viewDidLoad
function
var venues = JSON(jsonData!)
let d = venues.dictionaryValue
for (k, v) in venues {
resultKeys.append(k)
resultValues.append(v)
}
venuePicker.dataSource = self
venuePicker.reloadAllComponents()
Then inside titleForRow
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return resultValues[row]
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return resultValues.count
}
This way resultKeys[pickerView.selectedRowInComponent(0)]
will return the key for the selected value.
Upvotes: 1