我如何 link 使用进度视图下载文件

How can I link a file download with a Progress View

我下面的按钮代码从 URL 下载文件,我需要 link 它带有进度视图以显示下载进度。

@IBAction func btnStream(sender: UIButton) {

    //  First you need to create your audio url

    if let audioUrl = NSURL(string: "http://website.com/file.mp3") {

        // then lets create your document folder url
        let documentsUrl =  NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first as! NSURL

        // lets create your destination file url
        let destinationUrl = documentsUrl.URLByAppendingPathComponent(audioUrl.lastPathComponent!)
        println(destinationUrl)
        // to check if it exists before downloading it
        if NSFileManager().fileExistsAtPath(destinationUrl.path!) {
            println("The file already exists at path")

            // if the file doesn't exist
        } else {

            //  just download the data from your url
            if let myAudioDataFromUrl = NSData(contentsOfURL: audioUrl){
                // after downloading your data you need to save it to your destination url
                if myAudioDataFromUrl.writeToURL(destinationUrl, atomically: true) {
                    println("file saved")
                } else {
                    println("error saving file")
                }
            }
        }
    }

}

我如何 link 我的下载进度在 Swift 中使用进度视图?

勾选this tutorial。它在 Objective-C 中,但很容易转换为 Swift。

原理是在你的VC上实现一些NSURLConnectionDataDelegate功能:

  • connection:didReceiveResponse -> 您可以检索将要下载的文件的大小并用它估算下载百分比。
  • connection:didReceiveData -> 刷新函数,下载时会多次调用。您可以将不完整的 NSData 对象的大小与文件的大小进行比较。
  • connectionDidFinishLoading -> 此方法在下载过程结束时调用。

希望对您有所帮助,如果您在将 Obj-C 转换为 Swift 时遇到问题,请随时发表评论。

这是适合您的完整工作示例:

import UIKit

class ViewController: UIViewController, NSURLSessionDownloadDelegate {


    @IBOutlet weak var progressBar: UIProgressView!
    @IBOutlet weak var progressCount: UILabel!

    var task : NSURLSessionTask!

    var percentageWritten:Float = 0.0
    var taskTotalBytesWritten = 0
    var taskTotalBytesExpectedToWrite = 0

    lazy var session : NSURLSession = {
        let config = NSURLSessionConfiguration.ephemeralSessionConfiguration()
        config.allowsCellularAccess = false
        let session = NSURLSession(configuration: config, delegate: self, delegateQueue: NSOperationQueue.mainQueue())
        return session
        }()

    override func viewDidLoad() {
        progressBar.setProgress(0.0, animated: true)  //set progressBar to 0 at start
    }

    @IBAction func doElaborateHTTP (sender:AnyObject!) {

        progressCount.text = "0%"
        if self.task != nil {
            return
        }

        let s = "http://www.qdtricks.com/wp-content/uploads/2015/02/hd-wallpapers-1080p-for-mobile.png"
        let url = NSURL(string:s)!
        let req = NSMutableURLRequest(URL:url)
        let task = self.session.downloadTaskWithRequest(req)
        self.task = task
        task.resume()

    }

    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten writ: Int64, totalBytesExpectedToWrite exp: Int64) {
        println("downloaded \(100*writ/exp)")
        taskTotalBytesWritten = Int(writ)
        taskTotalBytesExpectedToWrite = Int(exp)
        percentageWritten = Float(taskTotalBytesWritten) / Float(taskTotalBytesExpectedToWrite)
        progressBar.progress = percentageWritten
        progressCount.text = String(format: "%.01f", percentageWritten*100) + "%"
    }

    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64) {
        // unused in this example
    }

    func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
        println("completed: error: \(error)")
    }

    // this is the only required NSURLSessionDownloadDelegate method

    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {

        let documentsDirectoryURL =  NSFileManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first as! NSURL
        println("Finished downloading!")
        println(documentsDirectoryURL)
        var err:NSError?

        // Here you can move your downloaded file
        if NSFileManager().moveItemAtURL(location, toURL: documentsDirectoryURL.URLByAppendingPathComponent(downloadTask.response!.suggestedFilename!), error: &err) {
            println("File saved")
        } else {
            if let err = err {
                println("File not saved.\n\(err.description)")

            }
        }

    }

}

可以使用NSURLSessionDownloadDelegate来实现,用户下载数据时会调用其方法。

这将向您显示进入 progressCount 标签的过程,并且 progressBar 将显示过程,因为计数会增加。您可以根据需要修改它。

您可以从 HERE 下载此示例。