NSURLSession delegates not called

后端 未结 3 1976
悲哀的现实
悲哀的现实 2020-12-06 16:04

In the following code, the file downloads just fine. However none of the delegate methods seem to be called as I receive no output whatsoever. the progressView is not update

相关标签:
3条回答
  • 2020-12-06 16:44

    Interestingly, Apple specifically explains this behavior in their NSURLSessionDataDelegate (but neither in the base delegate NSURLSessionTaskDelegate nor in NSURLSessionDownloadDelegate)

    NOTE

    An NSURLSession object need not have a delegate. If no delegate is assigned, when you create tasks in that session, you must provide a completion handler block to obtain the data.

    Completion handler block are primarily intended as an alternative to using a custom delegate. If you create a task using a method that takes a completion handler block, the delegate methods for response and data delivery are not called.

    0 讨论(0)
  • 2020-12-06 16:54

    From my testing, you have to choose whether you want to use a delegate or a completion handler - if you specify both, only the completion handler gets called. This code gave me running progress updates and the didFinishDownloadingToURL event:

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

    From the NSURLSession documentation, here's the relevant section:

    Like most networking APIs, the NSURLSession API is highly asynchronous. It returns data in one of two ways, depending on the methods you call:

    • To a completion handler block that returns data to your app when a transfer finishes successfully or with an error.
    • By calling methods on your custom delegate as the data is received.
    • By calling methods on your custom delegate when download to a file is complete.

    So by design it returns data to either a completion handler block or a delegate. But as evinced here, not both.

    0 讨论(0)
  • 2020-12-06 16:58

    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")
        }
    }
    
    0 讨论(0)
提交回复
热议问题