我正在 iOS 中开发一个应用程序,一切都很顺利,但有一个错误我无法修复。当用户第一次启动应用程序时,应用程序会从我的服务器请求一个 json。读取 json 时,我会在选择器 View 中显示结果。问题是 pickerview 总是显示为空,直到用户触摸屏幕。我已经尝试了很多东西,但没有任何效果。理论上它是空的,因为尚未读取 json,但事实并非如此,因为在控制台中我可以看到 json 已准备就绪。
相关代码如下:
override func viewDidLoad() {
super.viewDidLoad()
warning.isHidden = true
self.codeInput.delegate = self;
DispatchQueue.main.async {
self.readJson()
self.picker.reloadAllComponents()
}
}
以及我读取 json 的部分
func readJson(){
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(url: requestURL)
let session = URLSession.shared
let task = session.dataTask(with: urlRequest as URLRequest, completionHandler: {
(data, response, error) -> Void in
let httpResponse = response as! HTTPURLResponse
let statusCode = httpResponse.statusCode
if (statusCode == 200) {
print("Everyone is fine, file downloaded successfully.")
do{
let json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! [String:AnyObject]
if let events = json["events"] as? [[String: AnyObject]] {
for event in events {
//here I read the json and I save the data in my custom array
}
self.picker.reloadAllComponents()
}
print(self.eventsArray)
}
}catch {
print("Error with Json: \(error)")
}
}
else{
print(statusCode)
}
})
picker.reloadAllComponents()
task.resume()
}
最佳答案
你需要做几件事:
您需要将重新加载选择器 View 的调用移动到数据任务的完成处理程序中。加载数据后将调用该闭包。
但是,URLSession 任务的完成方法在后台线程上执行。因此,您需要将调用包装在对主线程的 GCD 调用中。将此代码添加为完成闭包中的最后一行,就在右大括号之前:
DispatchQueue.main.async{
picker.reloadAllComponents()
}
(这是 Swift 3 语法。)
编辑:
代码看起来像这样:
函数 readJson(){ 让 urlRequest: NSMutableURLRequest = NSMutableURLRequest(url: requestURL) 让 session = URLSession.shared let task = session.dataTask(with: urlRequest as URLRequest, completionHandler: { (data, response, error) -> Void in
let httpResponse = response as! HTTPURLResponse
let statusCode = httpResponse.statusCode
if (statusCode == 200) {
print("Everyone is fine, file downloaded successfully.")
do{
let json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! [String:AnyObject]
if let events = json["events"] as? [[String: AnyObject]] {
for event in events {
//here I read the json and I save the data in my custom array
}
//Delete this call to reloadAllComponents()
//self.picker.reloadAllComponents()
}
print(self.eventsArray)
}
//------------------------------------
//This is where the new code goes
DispatchQueue.main.async{
picker.reloadAllComponents()
}
//------------------------------------
}catch {
print("Error with Json: \(error)")
}
}
else{
print(statusCode)
}
})
//Delete this call to reloadAllComponents()
//picker.reloadAllComponents()
task.resume()
关于读取 Json 后 iOS PickerView 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40696619/