【发布时间】:2015-07-30 18:58:36
【问题描述】:
我正在开发一个文件夹/文件应用程序,用户可以在其中将文件下载到本地磁盘。每当用户下载文件时,我想显示一个显示进度的下载栏。
为此,我创建了一个协议,允许我的下载类和我的视图控制器进行通信:
协议:
protocol DownloadResponder : class {
func downloadFinished()
func downloadProgress(current:Int64, total:Int64)
}
下载类:
class fileDownloader: NSObject, NSURLSessionDelegate, NSURLSessionDownloadDelegate {
//responder
var responder : MyAwesomeDownloadResponder?
init(responder : MyAwesomeDownloadResponder) {
self.responder = responder
}
...
func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
println("downloaded \(100*totalBytesWritten/totalBytesExpectedToWrite)")
responder?.downloadProgress(totalBytesWritten, total: totalBytesExpectedToWrite)
}
...
}
然后在我的视图控制器中,我有一个触发downloadProgress 功能的下载按钮:
func downloadProgress(current:Int64, total:Int64) {
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
// do some task
var currentProgress = 100 * current / total
dispatch_async(dispatch_get_main_queue()) {
// update some UI
self.downloadLbl.text = "Downloaded \(currentProgress)%"
//set progress bar
self.progressBar.setProgress(Float(currentProgress), animated: true)
}
}
}
虽然控制台中的打印信息一直有效,但更新 UI 并不是很稳定。为了解决这个问题,我使用了在主线程上推送 UI 更改的 dispatch_async 方法。然而,虽然它总是第一次工作,弹回前一个视图控制器并再次返回,再次执行下载不会触发 UI 更新。进度条progressBar.setProgress 什么都不做,我的标签downloadLbl.text 不会自行更新。
有人知道解决这个问题的方法吗? 如果我的问题缺少信息,请告诉我,我会尝试补充现有信息。谢谢!
【问题讨论】:
标签: ios swift user-interface dispatch-async background-thread