如何判断何时可以重新加载表视图,以便它显示我已下载和解析的 JSON 数据?

Posted

技术标签:

【中文标题】如何判断何时可以重新加载表视图,以便它显示我已下载和解析的 JSON 数据?【英文标题】:How do I tell when the table view can be reloaded so that it shows JSON data I've downloaded and parsed? 【发布时间】:2019-04-16 20:38:43 【问题描述】:

我有一个应用程序可以从 URL 下载一些信息(即作者姓名、故事标题和封面图片)。我能够正确地从服务器下载和解析 JSON,但我被困在某一点上。

该应用由一个视图控制器(称为 ViewController.swift)和一个类文件(称为 GetStories.swift)组成。应用程序完成从服务器下载和解析 JSON 后,我希望 View Controller 中的表视图重新加载自身(self.tableView.reloadData())。

我在 GetStories.swift 中设置了完成块链,按顺序完成以下步骤: 1) 下载 JSON 2)解析JSON 3) 保存到磁盘

func updateUI()
    saveDownloadedAndParsedJSONToDisk 
    

func saveDownloadedAndParsedJSONToDisk(completionHandler: @escaping RefreshTableView)
    parseJSON 
        self.saveDataToJSON()
        completionHandler()
    

func parseJSON(completionHandler: @escaping ReadyToSave)
    downloadJSON  jsonPayload, error in
        do 
            if let data = jsonPayload 
                self.stories = try JSONDecoder().decode(Stories.self, from: data)
                if let stories = self.stories 
                    self.stories = stories
                    completionHandler()
                 else 
                    print("An error occurred while decoding JSON.")
                
             else if let error = error 
                print("Error retrieving data: \(error)")
            
         catch 
            print(error.localizedDescription)
        
    

func downloadJSON(completionHandler: @escaping NetworkResponse)
    let storiesAPIURL = URL(string: "\(wattpadAPIURL)")
    var wattpadAPIRequest = URLRequest(url: storiesAPIURL!)
    wattpadAPIRequest.httpMethod = "GET"
    let session = URLSession.shared
    let dataTask = session.dataTask(with: wattpadAPIRequest)  (data : Data?, response : URLResponse?, error : Error?) in
        if let data = data 
            completionHandler(data, nil)
         else if let error = error 
            completionHandler(nil, error)
            print(error.localizedDescription)
        
    
    dataTask.resume()

在 ViewController.swift 中,我调用 updateUI()。然后,我在协议中调用委托方法:

self.storyResults?.delegate?.didFinishFetchingAndParsingData(finished: true)

委托方法正在这样做:

    func didFinishFetchingAndParsingData(finished: Bool) 
    guard finished else 
        return
    
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) 
        self.tableView.reloadData()
        SVProgressHUD.dismiss()
    

所以,如您所见,我使用 0.5 秒的延迟来重新加载表格视图,因为我不确定如何判断下载、解析和保存完全完成的时间。

如果我不在委托方法中使用 0.5 秒的延迟,表格视图会在不适当的时间重新加载,并且不会显示任何结果。因此,以这种方式执行重新加载是行不通的:

        DispatchQueue.main.async 
        self.tableView.reloadData()
    

这样做的正确方法是什么?

提前致谢!

【问题讨论】:

【参考方案1】:

将委托调用移动到updateUI中的completionHandler,然后它将在适当的时候被调用。现在你有一个空的completionHandler。

func updateUI() 
    saveDownloadedAndParsedJSONToDisk 
        DispatchQueue.main.async 
            self.storyResults?.delegate?.didFinishFetchingAndParsingData(finished: true)
        
    

...

func didFinishFetchingAndParsingData(finished: Bool) 
    guard finished else 
        return
    

    self.tableView.reloadData()
    SVProgressHUD.dismiss()

【讨论】:

以上是关于如何判断何时可以重新加载表视图,以便它显示我已下载和解析的 JSON 数据?的主要内容,如果未能解决你的问题,请参考以下文章

实时重新加载表格视图

如何重新加载UIPageViewController以在Swift中重新加载其视图

自定义 UITableViewCell 背景,何时重新加载等

当方向改变时,视图中何时重新加载资源?

如何判断 Postgres 表何时聚集以及使用了哪些索引

如何检测 UIPageViewController 视图何时更改