我还是iOS开发的初学者。我正在使用Alamofire 4和SwiftyJSON来获取数据。当我调试时,我注意到它首先执行return country_list
,然后只去Alamofire体。我做了一些搜索,但仍未找到答案。
模型
import UIKit
import SwiftyJSON
import Alamofire
class CountryList {
var ReturnOK: String?
var Countryid: String?
var Countryname: String?
init(ReturnOK: String, Countryid: String, Countryname: String) {
self.ReturnOK = ReturnOK
self.Countryid = Countryid
self.Countryname = Countryname
}
/*
* Fetch the country list
*/
class func fetchCountryList() -> [CountryList] {
var country_list = [CountryList]()
// Add parameters
let param: [String: String] = [
Constants.LIST_COUNTRY.strAppID: Constants.OTHERS.temp_strAppID
]
Alamofire.request(Constants.LIST_COUNTRY.URL, parameters:param, encoding: URLEncoding.default).responseJSON { (response) in
switch response.result {
case .success(let value):
let json = JSON(value)
for (_, subJson):(String, JSON) in json {
let item = CountryList(
ReturnOK: subJson["ReturnOK"].stringValue,
Countryid: subJson["Countryid"].stringValue,
Countryname: subJson["Countryname"].stringValue)
country_list.append(item)
}
case .failure(let error):
print(error)
}
}
return country_list
}
}
的ViewController
class CreateAccountViewController: UIViewController, UITextViewDelegate, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate {
@IBOutlet weak var tf_country: UITextField!
@IBOutlet weak var picker_country: UIPickerView!
var countryL: [CountryList]?
override func viewDidLoad() {
super.viewDidLoad()
// Get the country list
countryL = CountryList.fetchCountryList()
print(countryL)
}
func textViewDidBeginEditing(_ textView: UITextView) {
if textView.textColor == UIColor.lightGray {
textView.text = nil
textView.textColor = UIColor.black
}
}
func textViewDidEndEditing(_ textView: UITextView) {
if textView.text.isEmpty {
textView.text = "Address"
textView.textColor = UIColor.lightGray
}
}
// Sets number of columns in picker view
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
// Sets the number of rows in the picker view
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if let countryL = countryL {
return countryL.count
} else {
return 0
}
}
// This function sets the text of the picker view to the content of the "salutations" array
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
let titleRow = (countryL?[row] as? String)!
return titleRow
}
// When user selects an option, this function will set the text of the text field to reflect
// the selected option.
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if (countryL?.count)! > 0 && (countryL?.count)! >= 0 {
self.tf_country.text = self.countryL?[row] as! String
self.picker_country.isHidden = true
}
}
func textFieldDidBeginEditing(_ textField: UITextField) {
// When select th texfield, begin editing
if (textField == self.tf_country) {
self.picker_country.isHidden = false
self.view.endEditing(true)
}
}
}
在Model I上我可以看到数据被追加。但是当我打印时,它是零。
非常感谢任何帮助。
答案 0 :(得分:3)
这里的想法是,您的Alamofire
函数是异步的,这意味着,当您致电return country_list
时,Alamofire
请求尚未完成。
你应该创建一个handler
喜欢
class func fetchCountries(handler: @escaping ([CountryList]) -> Void)) {
//alamofire request here
...
case .success(let value):
let json = JSON(value)
for (_, subJson):(String, JSON) in json {
let item = CountryList(
ReturnOK: subJson["ReturnOK"].stringValue,
Countryid: subJson["Countryid"].stringValue,
Countryname: subJson["Countryname"].stringValue)
country_list.append(item)
}
handler(countryList) //this return countryList from this functions
}
并在UIViewController
内,它看起来像
override func viewDidLoad() {
super.viewDidLoad()
// Get the country list
CountryList.fetchCountryList { [weak self] countryList in
guard let `self` = self else { //this here to avoid reference cycle
return
}
self.countryL = countryList
//update your UI here
print(countryL)
}
}