获得 json 响应后,Swift 4 UI 卡住了

Posted

技术标签:

【中文标题】获得 json 响应后,Swift 4 UI 卡住了【英文标题】:Swift 4 UI stuck after getting json response 【发布时间】:2018-02-05 22:46:23 【问题描述】:

我正在用 Swift 4 开发一个应用程序,并面临 json 解析的问题。数据和值一切正常,但是当我从 json 响应中获取数据并在 UI 中显示时,UI 会卡住几秒钟,直到我移动 UI 屏幕或单击文本字段。有时它工作正常,但在我点击 UI 之前大部分时间都卡住了。

我的代码是:

LoadCountries  jsonString in
    self.startAnimating()
    DispatchQueue.main.async 
        self.stopAnimating()
        print(jsonString)
    


func LoadCountries(completion:  @escaping ([Countries]) -> ()) 
    guard let url = URL(string: "https://www.adsfasdf.com/api/countries") else return
    URLSession.shared.dataTask(with: url)  (data, response, err) in
        do 
            let jsonString = try JSONDecoder().decode([Countries].self, from: data!)
            completion(jsonString)
         catch let jsonErr 
            print("Error serializing json:", jsonErr)
        
    .resume()

【问题讨论】:

可能不相关,但在完成处理程序中调用 startAnimating 没有任何意义。您应该在致电LoadCountries 之前致电它。此外,请遵守 Swift 命名约定,函数名和变量名使用 lowerCamelCase。 是的,完成处理程序可能没有在主线程上运行,所以 self.startAnimation 会导致这种延迟。 【参考方案1】:

这里是修正版,还请处理TODOs和weakselfs...

loadCountries  jsonString in
    DispatchQueue.main.async 
        self.stopAnimating()
        print(jsonString)
    


func loadCountries(completion: @escaping ([Countries]) -> ()) 
    // Note:assumes that loadCountries(...) is called on mainthread
    self.startAnimating()

    guard let url = URL(string: "https://www.adsfasdf.com/api/countries") else 
        // TODO:completion block not called?
        return
    
    URLSession.shared.dataTask(with: url)  (data, response, err) in
        do 
            // TODO: crash if data is nil
            let jsonString = try JSONDecoder().decode([Countries].self, from: data!)
            completion(jsonString)
         catch let jsonErr 
            // TODO:completion block not called?
            print("Error serializing json:", jsonErr)
        
    .resume()

【讨论】:

以上是关于获得 json 响应后,Swift 4 UI 卡住了的主要内容,如果未能解决你的问题,请参考以下文章

如何停止主 ui 线程,直到我得到来自 http 请求的响应

Swift 4 - Json 解码器

我如何使用解码器在swift 4中解析tableview中的json数组

Swift 2,如何从多阶段 JSON 响应中获取值

当试图打开Swagger-UI时只获得一个json Response

使用 Swift 4 Decodable 将字符串 JSON 响应转换为布尔值