下载状态在重新加载时消失

时间:2018-05-03 17:50:14

标签: swift download

我有一个从网站下载文件的下载功能。除了从导航控制器点击后退按钮并尝试重新加载视图控制器之外,一切都很有效。下载任务在后台运行正常但在第二次重新加载时重置视图。这是我的代码。

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask,
                didWriteData bytesWritten: Int64, totalBytesWritten: Int64,
                totalBytesExpectedToWrite: Int64) {
    // 1
    guard let url = downloadTask.originalRequest?.url,
        let download = downloadService.activeDownloads[url]  else { return }
    // 2
    download.progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
    // 3
    let totalSize = ByteCountFormatter.string(fromByteCount: totalBytesExpectedToWrite,
                                              countStyle: .file)

    // 4
    DispatchQueue.main.async {
        if let myCell = self.tableView.cellForRow(at: IndexPath(row: Int(download.resource.resourceId - 1) ,
                                                                   section: 0)) as? TranslationViewCell {
            myCell.updateDisplay(progress: download.progress, totalSize: totalSize)
            if download.isDownloading == true{
                myCell.downloadButton.isHidden = true //this doesnt get activated at all. 
                myCell.reloadInputViews()
            }
        }
    }
}

如果下载在后台运行,我试图隐藏下载按钮。

1 个答案:

答案 0 :(得分:2)

当视图控制器从堆栈中弹出时,它将被取消分配。这意味着' self'您在代码中引用不再存在,这使得无法更新视图。

为了第二次正确加载视图,您需要在未解除分配的代码中保留下载任务,或者使用类似事件的内容来响应下载任务本身。

此时我们可以进入iOS应用程序架构的整个讨论;但是,我会给你我最喜欢的选择,让这个工作。

发送通知,而不是直接与tableview交互。代码可能看起来像这样......

首先扩展您自己的应用的通知类:

extension Notification.Name {
    static let downloadProgressChanged = Notification.Name("download_progress_changed")
}

然后在回调期间发布通知:

DispatchQueue.main.async {
    let notificationDict:[String: Download] = ["download": download]
    NotificationCenter.default.post(name: .downloadProgressChanged, object: nil, userInfo: userDict)
}

然后你的视图控制器需要监听这些通知并适当更新,你应该在viewDidLoad中调用它

    // MARK - Notifications
func setupListeners() {
    NotificationCenter.default.addObserver(self, selector: #selector(handleProgressChanged(notification:)), name: .downloadProgressChanged, object: nil)
}

@objc func handleProgressChanged(notification: NSNotification) {
    if let download = notification.userInfo?["download"] as? <whatever the class of Download is> {
        // update the tableview here
    }
}

现在你有一个视图控制器可以适当地响应这个下载任务,而不需要知道任何关于任务的信息。