Состояние загрузки исчезает при перезагрузке - PullRequest
0 голосов
/ 03 мая 2018

У меня есть функция загрузки, которая загружает файлы с веб-сайта. Все работает отлично, за исключением того, что когда я нажимаю кнопку возврата на навигационном контроллере и пытаюсь перезагрузить контроллер вида. Задача загрузки работает в фоновом режиме, но сбрасывает представление при второй перезагрузке. Вот мой код

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 голосов
/ 22 мая 2018

Когда контроллер представления извлекается из стека, он освобождается. Это означает, что «я», на которое вы ссылаетесь в коде, больше не существует, что делает невозможным обновление представления.

Чтобы правильно загрузить представление во второй раз, вам нужно удерживать задачу загрузки в коде, который не освобождается, или использовать что-то вроде событий для ответа на саму задачу загрузки.

На этом этапе мы могли бы перейти к полному обсуждению архитектуры приложений для iOS; однако я дам тебе мой любимый вариант, чтобы заставить это работать.

Отправлять уведомления, а не напрямую взаимодействовать с таблицей. Код может выглядеть примерно так ...

Сначала расширьте класс уведомлений для вашего собственного приложения:

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

Теперь у вас есть контроллер представления, который может реагировать на эту задачу загрузки соответствующим образом, не имея необходимости вообще что-либо знать о задаче.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...