How can I link a file download with a Progress View

Mike Sylver picture Mike Sylver · May 18, 2015 · Viewed 9.1k times · Source

My button code below download a file from a URL, I need to link it with a Progress View to show the Downloading Progress.

@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")
                }
            }
        }
    }

}

How can i link my downloading progress with a Progress View in Swift?

Answer

Dharmesh Kheni picture Dharmesh Kheni · May 18, 2015

Here is complete working example for you:

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)")

            }
        }

    }

}

You can use NSURLSessionDownloadDelegate to achieve this whose method will be called when user downloading data.

This will show you the process into progressCount label and the progressBar will show process as count will increment. you can modify this as per your need.

You can download this example from HERE.