Search code examples
iosiphonexcodeswiftuiprogressview

How can I link a file download with a Progress View


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?


Solution

  • 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.