【问题标题】:Swift: Cant get progress of URLSessionDownload in delegate?Swift:在委托中无法获得 URLSession 下载的进度?
【发布时间】:2017-12-04 22:47:27
【问题描述】:

好的,我以前从未保存过文件(在本例中为 m4as),不知道我是否正确执行此操作,而且无法获取 URL 的下载进度,尽管此处包含所需的 URLSessionDownloadDelegate 函数:

 func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
        if totalBytesExpectedToWrite > 0 {
            let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
            print("Progress \(downloadTask) \(progress)")
        }
    }

    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        print("Download finished: \(location)")
        try? FileManager.default.removeItem(at: location)
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        print("Task completed: \(task), error: \(error)")
    }

我从教程中得到了这些,但是没有任何东西打印到控制台。我尝试调用这些函数,但我不知道从哪里获取 downloadTask var 或会话。

这就是我下载文件的方式,这是可行的:

func goDownload()
    {
        if let audioUrl = testUrl { //set at beginning

            // then lets create your document folder url
            let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!

            // lets create your destination file url
            let destinationUrl = documentsDirectoryURL.appendingPathComponent(audioUrl.lastPathComponent)
            print(destinationUrl)

            // to check if it exists before downloading it
            if FileManager.default.fileExists(atPath: destinationUrl.path) {
                print("********** The file already exists at path")

                // if the file doesn't exist
            } else {
                // you can use NSURLSession.sharedSession to download the data asynchronously
            URLSession.shared.downloadTask(with: audioUrl, completionHandler: { (location, response, error) -> Void in
                    guard let location = location, error == nil else { return }
                    do {
                        // after downloading your file you need to move it to your destination url
                        try FileManager.default.moveItem(at: location, to: destinationUrl)

                        //success
                        print("************** SUCCESS File moved to documents folder", audioUrl)
                        self.playModeStreaming = false

                        self.pausePlay()
                        AudioPlayerManager.shared.play(url: audioUrl)

                    } catch let error as NSError {
                        print(error.localizedDescription)
                    }
                }).resume()
            }
        }
    }

但是,即使我尝试从此处获取 downloadTask,我也会遇到类型问题。如何使用此下载函数获取下载进度(收到的字节数等)?

编辑:这就是我所拥有的:

 var session = URLSession()
    let sessDelegate = CustomDelegate()
self.session = URLSession(configuration: .default, delegate: sessDelegate, delegateQueue: nil)

然后将上述函数中的 URLSession.shared 替换为session

我的自定义委托类单独:

class CustomDelegate : NSObject, URLSessionDataDelegate, URLSessionTaskDelegate {

    //define all  `NSURLSessionDataDelegate` and `NSURLSessionTaskDelegate` methods here
    //URLSessionDelegate methods

    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
        if totalBytesExpectedToWrite > 0 {
            let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
            print("Progress \(downloadTask) \(progress)")
        }
    }

    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        print("Download finished: \(location)")
        try? FileManager.default.removeItem(at: location)
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        print("Task completed: \(task), error: \(error)")
    }

}

【问题讨论】:

  • 您将委托设置为自己。相反,您应该实例化您的 CustomDelegate 类的实例并将其设置为您的“self.session”的委托
  • 我做到了。在这里我会更新我的问题,我没有更新那部分
  • 怎么了?是我的下载功能吗?
  • 你在调用 session.resume() 吗?
  • 是的。看看下载功能就在那里。

标签: swift swift3 download nsurlsession nsurlsessiondownloadtask


【解决方案1】:

您可以添加自定义委托类,并实现NSURLSessionDataDelegateNSURLSessionTaskDelegate 协议。

class CustomDelegate : NSObject, NSURLSessionDataDelegate, NSURLSessionTaskDelegate {

//define all  `NSURLSessionDataDelegate` and `NSURLSessionTaskDelegate` methods here

}

现在像这样创建上述类的实例:

let myCustomDelegate = CustomDelegate();

然后您需要像这样设置NSURLSession 实例的委托属性:

目标 C

NSURLSession *session=[NSURLSession sessionWithConfiguration:sessionConfig delegate:myCustomDelegate delegateQueue:nil];

SWIFT 3

let session = URLSession(configuration: .default, delegate: myCustomDelegate, delegateQueue: nil)

参考链接:

  1. NSURLSession Class Reference
  2. From NSURLConnection to NSURLSession

【讨论】:

  • 你能用 Swift 回答吗,我是新手
  • 你能用 Swift 写出代码吗?第二个链接不起作用
  • 对于 Swift 2.0 代码,您可以尝试使用 'NSURLSession' 而不是 'URLSession'
  • 好的,谢谢,我这样做了,但仍然没有调用函数。
  • 没关系。好的,我做到了,并在我的会话中设置了该委托。依然没有。查看我的编辑
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多