2015-05-18 6 views
5

Il mio codice di pulsante sotto scarica un file da un URL, ho bisogno di collegarlo con una vista di avanzamento per mostrare il progresso di download.Come posso collegare un download di file con una vista di avanzamento

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

} 

Come posso collegare il mio stato dello scaricamento con una vista Progress a Swift?

risposta

5

Ecco esempio di lavoro completo per voi:

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

      } 
     } 

    } 

} 

È possibile utilizzare NSURLSessionDownloadDelegate per raggiungere questo obiettivo il cui metodo sarà chiamato quando l'utente lo scaricamento dei dati.

Questo mostrerà il processo nell'etichetta progressCount e lo progressBar mostrerà il processo man mano che il conteggio aumenterà. puoi modificarlo secondo le tue necessità.

È possibile scaricare questo esempio da HERE.

+0

Dharmesh Kheni, l'esempio funziona bene ma dove salvate il file? –

+0

controlla la mia risposta aggiornata. –

+0

Ciao @DharmeshKheni. Come lavorare per più URL. Sto provando solo questo. Non potevo. Se il 2 ° URL sta progredendo, in quel momento se inizio terzo URL significa, il 2 ° viene fermato. Non so eseguire tutti gli URL in concorrenza. Sto cercando in fretta. Pls mi guida. –

2

Controllare this tutorial. È in Objective-C, ma sarà facile convertirlo in Swift.

Il principio è quello di implementare alcune funzioni NSURLConnectionDataDelegate sul VC:

  • collegamento: didReceiveResponse -> È possibile recuperare la dimensione del file che verrà scaricato e stimare la percentuale di download con esso.
  • connessione: didReceiveData -> È la funzione di aggiornamento, verrà chiamata più volte durante il download. Puoi confrontare la dimensione del tuo oggetto NSData incompleto con la dimensione del file.
  • connectionDidFinishLoading -> Questo metodo viene chiamato alla fine del processo di download.

Spero che ti aiuti e non esitare a commentare se hai qualche problema a convertire Obj-C in Swift.