NSFetchedResultsController не обновляется постоянно - PullRequest
0 голосов
/ 21 февраля 2019

Привет! Я перешел от использования NSKeyedArchiver к использованию CoreData

Меня заинтересовало класс NSFetchedResultsController и его преимущества с моим приложением UITableView.

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

Но процесс загрузки, безусловно, происходит.вот мой код.

NSFetchedResultsController реализован в классе модели, который является singleton

    lazy var fetchedResultsController: NSFetchedResultsController<RCDownload> = {

    let request: NSFetchRequest<RCDownload> = RCDownload.fetchRequest()
    let sortDiscriptor = NSSortDescriptor(key: #keyPath(RCDownload.startDate), ascending: false)
    request.sortDescriptors = [sortDiscriptor]
    let fetchedResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: sharedCoreDataController.getContext(), sectionNameKeyPath: nil, cacheName: nil)

    do {
        try fetchedResultsController.performFetch()
    } catch {
        fatalError("failed to fetch downloads")
    }

    return fetchedResultsController
}()

, тогда код UITableView выглядит следующим образом

    override func viewDidLoad() {
    super.viewDidLoad()

    self.navigationController!.navigationBar.prefersLargeTitles = true
    sharedDownloadController.fetchedResultsController.delegate = self
}

    func configureCell(tableView: UITableView, cellForRowAt indexPath: IndexPath) {

    guard let cell = tableView.cellForRow(at: indexPath) as? RCDownloadTVCell else {
        return
    }
    let download = sharedDownloadController.fetchedResultsController.object(at: indexPath)
    let downloadState = download.descriptionAsState()
    let downloaded = Double(download.downloadedBytes) / 1000000
    let downloadSize = Double(download.fileSize) / 1000000
    if downloaded > 0 {
        cell.fileDescription.text = String(format: "%.1fMB of %.1fMB", downloaded, downloadSize)
    } else {
        cell.fileDescription.text = String("Loading...")
    }
    cell.fileName.text = download.fileName
    cell.progressView.setProgress(download.progressPercentage, animated: false)

    DispatchQueue.main.async {
        switch downloadState {
        case .downloading:
            cell.actionButton.tintColor = UIColor.blue
            cell.actionButton.setTitle("Pause", for: [])
        case .suspended:
            cell.actionButton.tintColor = UIColor.blue
            cell.actionButton.setTitle("Resume", for: [])
        case .cancelled:
            cell.actionButton.tintColor = UIColor.red
            cell.actionButton.setTitle("Resume", for: [])
        case .finished:
            cell.actionButton.tintColor = UIColor.red
            cell.actionButton.setTitle("Done", for: [])
        }
    }
}

extension RCDownloadsTVC: NSFetchedResultsControllerDelegate {

func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    DispatchQueue.main.async {
        self.tableView.beginUpdates()
    }
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
    DispatchQueue.main.async {
        self.tableView.endUpdates()
    }
}

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {

    DispatchQueue.main.async {
        switch type {
        case .insert:
            guard let newIndexPath = newIndexPath else {
                fatalError()
            }
            self.tableView.insertRows(at: [newIndexPath], with: .right)
            self.reloadData()
            break
        case .update:
            guard let indexPath = indexPath else {
                fatalError()
            }
            self.configureCell(tableView: self.tableView, cellForRowAt: indexPath)
            break
        case .move:

            break
        case .delete:
            guard let indexPath = indexPath else {
                fatalError()
            }
            self.tableView.deleteRows(at: [indexPath], with: .left)
            break
        }
    }
}

}

RCDownload обновляется с использованием URLSession didWriteData метода

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {

    let predicate = NSPredicate(format: "taskIdentifier == %d", Int16(downloadTask.taskIdentifier) as CVarArg)
    let downloads = self.fetchDownloadsWith(predicate: predicate)
    if downloads.isEmpty != true {
        let download = downloads[0]
        if let fileName = downloadTask.response?.suggestedFilename {
            download.fileName = fileName
        } else {
            download.fileName = downloadTask.response?.url?.lastPathComponent
        }
        download.fileSize = totalBytesExpectedToWrite
        download.downloadedBytes = totalBytesWritten
        download.progressPercentage = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
    }
}

PS: пожалуйста, если какой-либо код все еще необходим, просто дайте мне знатьобновить.

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