Swift:在委托中无法获得URLSessionDownload的进度?

时间:2017-06-30 22:21:29

标签: swift swift3 download nsurlsession nsurlsessiondownloadtask

好吧,我之前从未保存过文件(在这种情况下为m4)并且不知道我是否正确执行此操作而且无法获取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)

然后在上面的函数中用session替换了URLSession.shared。

我的自定义委托类:

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

}

1 个答案:

答案 0 :(得分:0)

您可以添加自定义委托类,并实施NSURLSessionTaskDelegateclass CustomDelegate : NSObject, NSURLSessionDataDelegate, NSURLSessionTaskDelegate { //define all `NSURLSessionDataDelegate` and `NSURLSessionTaskDelegate` methods here } 协议。

let myCustomDelegate = CustomDelegate();

现在像这样创建一个上面的类的实例:

NSURLSession

然后,您需要设置NSURLSession *session=[NSURLSession sessionWithConfiguration:sessionConfig delegate:myCustomDelegate delegateQueue:nil]; 实例的委托属性,如下所示:

目标C

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

SWIFT 3

{{1}}

参考链接:

  1. NSURLSession Class Reference
  2. From NSURLConnection to NSURLSession