Обновление UI Dispatch_Async скачать фоновый рисунок Swift

Im работает над приложением папок / файлов, где пользователи могут загружать файлы на локальный диск. Всякий раз, когда пользователь загружает файл, я хочу показать панель загрузки, в которой отображается прогресс.

для этого я создал протокол, который позволяет моему классу загрузки и моему контроллеру представления общаться:

протокол:

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) } } } 

Хотя печать информации на консоли работает все время, обновление пользовательского интерфейса не было действительно стабильным. Чтобы исправить это, я использовал метод dispatch_async, который нажимал изменение пользовательского интерфейса в основном потоке. Тем не менее, хотя он всегда работает в первый раз, возвращаясь к предыдущему контроллеру представления и возвращаясь снова, выполнение загрузки еще раз не вызывает обновление пользовательского интерфейса. Progress bar progressBar.setProgress ничего не делает, и моя метка downloadLbl.text не обновляется сама.

Кто-нибудь есть идея о том, как это решить? Если в моем вопросе отсутствует информация, сообщите мне, и я попытаюсь добавить существующую информацию. Благодаря!

Поскольку я не получал / не нашел решения для своей проблемы, я вернулся на более высокий уровень и изменил способ общения между моими классами, чтобы обрабатывать изменения ui, основанные на переходе потока загрузки фона.

Вместо того, чтобы использовать протоколы, я пошел на уведомления, и он решил мою проблему.

Внутри класса загрузки:

 func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { println("downloaded \(100*totalBytesWritten/totalBytesExpectedToWrite)") //NOTIFICATION // notify download progress! var fileInfo = [NSObject:AnyObject]() fileInfo["fileId"] = fileDownloader.storageInfo[downloadTask.taskIdentifier]!["id"] as! Int! fileInfo["fileCurrent"] = Float(totalBytesWritten) fileInfo["fileTotal"] = Float(totalBytesExpectedToWrite) let defaultCenter = NSNotificationCenter.defaultCenter() defaultCenter.postNotificationName("DownloadProgressNotification", object: nil, userInfo: fileInfo) } 

внутри контроллера вида:

 override func viewDidLoad() { super.viewDidLoad() // ready for receiving notification let defaultCenter = NSNotificationCenter.defaultCenter() defaultCenter.addObserver(self, selector: "handleCompleteDownload:", name: "DownloadProgressNotification", object: nil) } func handleCompleteDownload(notification: NSNotification) { let tmp : [NSObject : AnyObject] = notification.userInfo! // if notification received, change label value var id = tmp["fileId"] as! Int! var current = tmp["fileCurrent"] as! Float! var total = tmp["fileTotal"] as! Float! var floatCounter = 100 * current / total var progressCounter = String(format: "%.f", floatCounter) if(id == self.fileId){ let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT dispatch_async(dispatch_get_global_queue(priority, 0)) { // do some task dispatch_async(dispatch_get_main_queue()) { // update some UI self.downloadLbl.text = "Downloaded \(progressCounter)%" self.progressBar.setProgress((progressCounter as NSString).floatValue, animated: true) } } } } 

надеюсь, что это поможет!

Interesting Posts
Давайте будем гением компьютера.