ios - 我如何知道何时可以重新加载 TableView ,以便它显示我下载和解析的 JSON 数据?

标签 ios swift

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

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

我在 GetStories.swift 中设置了一系列完成 block ,它们按顺序完成以下步骤: 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()。然后,我在协议(protocol)中调用委托(delegate)方法:

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

委托(delegate)方法是这样做的:

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

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

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

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

执行此操作的正确方法是什么?

提前致谢!

最佳答案

将委托(delegate)调用移至 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()
}

关于ios - 我如何知道何时可以重新加载 TableView ,以便它显示我下载和解析的 JSON 数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55716284/

相关文章:

ios - 同时处理多个手势

ios - 为 iOS Metal 中的 MTLBuffer 使用的数据分配内存

ios - 来自蓝牙模块的未知数据类型

ios - 将枚举值设置为核心数据对象

ios - 关闭 UIPrintInteractionController

iOS 7 master 有导航栏提示时的细节布局

swift - 无法创建用于查询嵌套父项的 Fluent ORM 查询

ios - 无法理解 Collection View 中的恢复单元格

swift - 如何为我的枚举返回空白值

ios - 将标题设置为 UIBarButtonItem