xcode 如何将文件下载链接到进度视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30295805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 07:09:55  来源:igfitidea点击:

How can I link a file download with a Progress View

iosiphonexcodeswiftuiprogressview

提问by Mike Sylver

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

我下面的按钮代码从 URL 下载文件,我需要将它与进度视图链接以显示下载进度。

@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?

如何将我的下载进度与 Swift 中的进度视图相关联?

采纳答案by Dharmesh Kheni

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 NSURLSessionDownloadDelegateto achieve this whose method will be called when user downloading data.

您可以使用它NSURLSessionDownloadDelegate来实现此目的,当用户下载数据时将调用其方法。

This will show you the process into progressCountlabel and the progressBarwill show process as count will increment. you can modify this as per your need.

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

You can download this example from HERE.

你可以从这里下载这个例子。

回答by Pintouch

Check this tutorial. It's in Objective-C, but it will be easy to convert to Swift.

检查本教程。它在 Objective-C 中,但很容易转换为 Swift。

The principle is to implement some NSURLConnectionDataDelegatefunctions on your VC :

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

  • connection:didReceiveResponse-> You can retrieve the size of the file that will be downloaded and estimate the download percentage with it.
  • connection:didReceiveData-> It's the refresh function, it will be called multiple times during the download. You can compare the size of your incomplete NSData object with the size of the file.
  • connectionDidFinishLoading-> This method is called at the end of the download process.
  • connection:didReceiveResponse-> 您可以检索将要下载的文件的大小并估计下载百分比。
  • connection:didReceiveData-> 它是刷新函数,在下载过程中会被多次调用。您可以将不完整的 NSData 对象的大小与文件的大小进行比较。
  • connectionDidFinishLoading-> 在下载过程结束时调用此方法。

Hope it helps, and don't hesitate to comment if you have some troubles converting Obj-C to Swift.

希望它有所帮助,如果您在将 Obj-C 转换为 Swift 时遇到一些麻烦,请不要犹豫,发表评论。