NSURLSession委托没有被调用

在下面的代码中,文件下载就好了。 然而没有一个委托方法似乎被调用,因为我没有收到任何输出。 progressView也不更新。 任何想法为什么?

import Foundation import UIKit class Podcast: PFQueryTableViewController, UINavigationControllerDelegate, MWFeedParserDelegate, UITableViewDataSource, NSURLSessionDelegate, NSURLSessionDownloadDelegate { func downloadEpisodeWithFeedItem(episodeURL: NSURL) { var request: NSURLRequest = NSURLRequest(URL: episodeURL) let config = NSURLSessionConfiguration.defaultSessionConfiguration() let session = NSURLSession(configuration: config, delegate: self, delegateQueue: nil) var downloadTask = session.downloadTaskWithURL(episodeURL, completionHandler: { (url, response, error) -> Void in println("task completed") if (error != nil) { println(error.localizedDescription) } else { println("no error") println(response) } }) downloadTask.resume() } func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64) { println("didResumeAtOffset") } func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { var downloadProgress = Double(totalBytesWritten) / Double(totalBytesExpectedToWrite) println(Float(downloadProgress)) println("sup") epCell.progressView.progress = Float(downloadProgress) } func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) { println(location) } } 

从我的testing中,您必须select是否要使用委托或完成处理程序 – 如果您同时指定了两者,则只会完成处理程序的调用。 这段代码给了我运行进度更新和didFinishDownloadingToURL事件:

 func downloadEpisodeWithFeedItem(episodeURL: NSURL) { let request: NSURLRequest = NSURLRequest(URL: episodeURL) let config = NSURLSessionConfiguration.defaultSessionConfiguration() let session = NSURLSession(configuration: config, delegate: self, delegateQueue: NSOperationQueue.mainQueue()) let downloadTask = session.downloadTaskWithURL(episodeURL) downloadTask.resume() } func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64) { println("didResumeAtOffset: \(fileOffset)") } func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { var downloadProgress = Double(totalBytesWritten) / Double(totalBytesExpectedToWrite) println("downloadProgress: \(downloadProgress)") } func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) { println("didFinishDownloadingToURL: \(location)") println(downloadTask) } 

NSURLSession文档 ,这里是相关的部分:

像大多数networkingAPI一样,NSURLSession API是高度asynchronous的。 它以两种方式之一返回数据,具体取决于您调用的方法:

  • 当传输成功完成或发生错误时,将数据返回到应用程序的完成处理程序块。
  • 在收到数据时调用自定义委托上的方法。
  • 下载到文件完成时,通过调用自定义委托上的方法。

所以通过devise,它将数据返回到完成处理程序块委托。 但正如这里所显示的,不是两者。

有趣的是, 苹果专门在他们的NSURLSessionDataDelegate解释了这种行为 (但是在基本委托NSURLSessionTaskDelegateNSURLSessionTaskDelegate没有)

注意

一个NSURLSession对象不需要委托。 如果未分配任何委托,则在该会话中创build任务时,必须提供完成处理程序块以获取数据。

完成处理程序块主要用作使用自定义委托的替代方法。 如果使用带有完成处理程序块的方法创build任务,则不会调用响应和数据传递的委托方法。

Swift 3

 class ViewController: UIViewController { var urlLink: URL! var defaultSession: URLSession! var downloadTask: URLSessionDownloadTask! } // MARK: Button Pressed @IBAction func btnDownloadPressed(_ sender: UIButton) { let urlLink1 = URL.init(string: "https://github.com/VivekVithlani/QRCodeReader/archive/master.zip") startDownloading(url: urlLink!) } @IBAction func btnResumePressed(_ sender: UIButton) { downloadTask.resume() } @IBAction func btnStopPressed(_ sender: UIButton) { downloadTask.cancel() } @IBAction func btnPausePressed(_ sender: UIButton) { downloadTask.suspend() } func startDownloading (url:URL) { let backgroundSessionConfiguration = URLSessionConfiguration.background(withIdentifier: "backgroundSession") defaultSession = Foundation.URLSession(configuration: backgroundSessionConfiguration, delegate: self, delegateQueue: OperationQueue.main) downloadProgress.setProgress(0.0, animated: false) downloadTask = defaultSession.downloadTask(with: urlLink) downloadTask.resume() } // MARK:- URLSessionDownloadDelegate func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { print("File download succesfully") } func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) { downloadProgress.setProgress(Float(totalBytesWritten)/Float(totalBytesExpectedToWrite), animated: true) } func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { downloadTask = nil downloadProgress.setProgress(0.0, animated: true) if (error != nil) { print("didCompleteWithError \(error?.localizedDescription)") } else { print("The task finished successfully") } }