iosswiftuitableviewuiprogressview

Show download progress in UITableviewCell


I'm iOS Developer.I want to implement functionality like,there are multiple files display in UITableview with File name,UIProgressView and download button.I want to implement if user click on download button then start downloading file with updating UIProgressView value for that cell,if I click on another cell's download button then both file should be download simultaneously with downloading status. please help me if anyone have idea. here is my code

import UIKit

class PDFCell: UITableViewCell,URLSessionTaskDelegate,URLSessionDownloadDelegate {

    @IBOutlet weak var btnStartDownload: UIButton!
    @IBOutlet weak var downloadProgress: UIProgressView!
    var url:String?
    var percentageWritten: Float = 0.0
    var taskTotalBytesWritten = 0
    var taskTotalBytesExpectedToWrite = 0
    var task: URLSessionTask!
    let config = URLSessionConfiguration.background(withIdentifier: "lanet.PDFDownload")
    lazy var session: URLSession = {
        URLSession(configuration: config, delegate: self as! URLSessionDelegate, delegateQueue: OperationQueue())
    }()
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
        if totalBytesExpectedToWrite > 0 {
            let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
            DispatchQueue.main.async {
                self.downloadProgress.progress = progress
            }
            debugPrint("Progress \(downloadTask) \(progress)")
        }
    }
    override func prepareForReuse() {
        super.prepareForReuse()
        self.url = ""
    }
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        let path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
        let documentDirectoryPath:String = path[0]
        let fileManager = FileManager()
        let destinationURLForFile = URL(fileURLWithPath: documentDirectoryPath.appendingFormat("/file.pdf"))
        if fileManager.fileExists(atPath: destinationURLForFile.path){
            // showFileWithPath(path: destinationURLForFile.path)
        }
        else{
            do {
                try fileManager.moveItem(at: location, to: destinationURLForFile)
                // show file
                // showFileWithPath(path: destinationURLForFile.path)
            }catch{
                print("An error occurred while moving file to destination url")
            }
        }

        debugPrint("Download finished: \(location)")
        try? FileManager.default.removeItem(at: location)
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        debugPrint("Task completed: \(task), error: \(error)")
    }


    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

    @IBAction func btnDownloadClick(_ sender: Any) {
        let url = URL(string: self.url!)!
        let task = session.downloadTask(with: url)
        task.resume()
    }
}

} enter image description here


Solution

  • Go through this tutorial for basic reference: https://www.raywenderlich.com/158106/urlsession-tutorial-getting-started

    In section download progress you will see

    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 trackCell = self.tableView.cellForRow(at: IndexPath(row: download.track.index,
          section: 0)) as? TrackCell {
          trackCell.updateDisplay(progress: download.progress, totalSize: totalSize)
        }
      }
    }