读取 Json 后 iOS PickerView 为空

标签 ios json swift3

我正在 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/

相关文章:

ios - 一旦发现用户的位置,使当前位置出现在 map 上 swift 3

ios - Xcode 11 中没有这样的模块 'PackageDescription'

objective-c - 如何访问呈现模态视图的 UIViewController 类/类名?

javascript - 有没有办法从音频文件中获取诸如分贝级别之类的信息并将该信息转换为 json 数组?

json - 如何使用 jq 将多个字段连接到同一行

swift - Swift 3 中 DispatchQueue 上的 AutoreleaseFrequency

ios - 扫描二维码后如何进入新的 View Controller ?

ios - 连接可用后立即触发操作

javascript - AngularJS:$http 请求问题 - DOM 未针对 jQuery 函数调用更新

audio - Swift:即使我明确设置了启用按钮,命令中心也无法正常工作?