将进度条添加到下载文件[重复]

Posted

技术标签:

【中文标题】将进度条添加到下载文件[重复]【英文标题】:Add progress-bar to Download file [duplicate] 【发布时间】:2018-07-24 22:06:42 【问题描述】:

我正在实现一个 ViewController 来显示以前从我的服务器下载并存储在设备本地的 PDF,它可以正常工作,但是下载 PDF 需要太多时间,我想实现一个 progress-bar

我的代码如下,我尝试在其中实现 @IBOutlet weak var downloadBar: UIProgressView!当我得到下载所需的时间,所以我吃我的代码达到 100% 并且下载还没有结束。

class PDFViewController: UIViewController 
    @IBOutlet weak var pdfView: PDFView!

    @IBOutlet weak var downloadBar: UIProgressView!

    //*******
    var downloader = Timer()
    var minValue = 0
    var maxValue = 100
    //********

    var namePDF:String?

    override func viewDidLoad() 
        super.viewDidLoad()

        downloadBar.setProgress(0, animated: false)


        if let pdfUrl = URL(string: "https://miserver.com/\(namePDF!).pdf") 


            print(pdfUrl)

            // then lets create your document folder url
            let documentsDirectoryURL =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!

            // lets create your destination file url
            let destinationUrl = documentsDirectoryURL.appendingPathComponent(pdfUrl.lastPathComponent)
            print(destinationUrl)

            // to check if it exists before downloading it
            if FileManager.default.fileExists(atPath: destinationUrl.path) 
                print("The file already exists at path")

                /************** show pdf ****************/
                let pdfUrl = destinationUrl.path
                let rutafile = URL(fileURLWithPath: pdfUrl)
                print(pdfUrl)
                if let document = PDFDocument(url: rutafile) 
                    pdfView.autoScales = true
                    pdfView.document = document
                
                 /************** end show pdf ****************/


                // if the file doesn't exist
             else 
                 print("file doesn't exist")

                downloader = Timer.scheduledTimer(timeInterval: 0.06, target: self, selector: (#selector(PDFViewController.updater)), userInfo: nil, repeats: true)
                downloadBar.setProgress(0, animated: false)

                // you can use NSURLSession.sharedSession to download the data asynchronously
                URLSession.shared.downloadTask(with: pdfUrl, completionHandler:  (location, response, error) -> Void in
                    guard let location = location, error == nil else  return 
                    do 
                        // after downloading your file you need to move it to your destination url
                        try FileManager.default.moveItem(at: location, to: destinationUrl)
                        print("File moved to documents folder")

                        print("file has already been downloaded")
                        /************** show pdf ****************/
                        let pdfUrl = destinationUrl.path
                        let rutafile = URL(fileURLWithPath: pdfUrl)
                        print(pdfUrl)
                        if let document = PDFDocument(url: rutafile) 
                            self.pdfView.autoScales = true
                            self.pdfView.document = document
                        
                        /************** show pdf ****************/

                     catch let error as NSError 
                        print(error.localizedDescription)
                    
                ).resume()
            
        



    

@objc func updater() 

    if minValue != maxValue 
        minValue += 1
        downloadBar.progress = Float(minValue) / Float(maxValue)

        print(Float(minValue) / Float(maxValue))
     else 
        minValue = 0
        downloader.invalidate()
    

已经非常感谢你了

【问题讨论】:

你为什么使用定时器? var 下载器 = Timer().您是否还面临 IBOutlet 的问题或没有显示进度? 当您想显示进度时,为shared 调用downloadTask(with:completionHandler:) 并不是最好的方法。创建一个配置了委托的URLSession,并正确准备委托方法,然后将downloadTask(with:)用于创建的实例。我没有足够的时间来写答案,希望您能尽快找到正确的方向。 @Asim Progress 如果显示(进度条有效),但我的问题是它在没有完成下载文件的情况下达到 100 的时间。如何获得下载所需的时间? ***.com/q/30047706/2303865 【参考方案1】:

您可以实现 URLSessionDownloadDelegate 协议。然后使用以下方法:

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) 
    if totalBytesExpectedToWrite > 0 
        let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)

        self.downloadBar.setProgress(progress, animated: false)
    

这只会在写入新字节时更新进度条。并准确估计您的下载进度。希望这会有所帮助:)

【讨论】:

如何使用这个 URLSessionDownoadDelegate 协议?我的意思是哪个类应该符合它?能详细回答一下吗? 只需将协议与您从中调用它的类保持一致,例如您要更新进度的相应 ViewController。并听听上述功能的进展情况。每次取得进度时都会调用该函数,您可以将更新的进度分配给进度条。

以上是关于将进度条添加到下载文件[重复]的主要内容,如果未能解决你的问题,请参考以下文章

数据导出进度条

VC下载文件 + 显示进度条

显示下载进度条

NSURLSession 下载任务 - 进度条问题

下载文件时进度条不显示剩余百分比?

为多个文件下载添加子进度