Search code examples
swifturlsession

URLSessionDelegate methods not called


Firstly, I already checked similar existing questions, and none of the answers apply.
NSURLSession delegates not called
URLSessionDelegate Function Not Being Called

I am trying to download a file using URLSessionDownloadTask, like so

class MyNetworkManager : NSObject
{
    static let instance = MyNetworkManager()

    var downloadSession : URLSession?

    init()
    {
        super.init()

        let downloadConfiguration = URLSessionConfiguration.default
        downloadSession = URLSession(configuration: downloadConfiguration, delegate: self, delegateQueue: nil)
    }

    func download(_ url : URL)
    {
        var urlRequest = URLRequest(url: url)
        urlRequest.httpMethod = "GET"
        let downloadTask = downloadSession?.downloadTask(with: urlRequest)

        downloadTask?.resume()
    }
}

extension MyNetworkManager : URLSessionDelegate
{
    func urlSession(_ session: URLSession,
                    downloadTask: URLSessionDownloadTask,
                    didWriteData bytesWritten: Int64,
                    totalBytesWritten: Int64,
                    totalBytesExpectedToWrite: Int64)
    {
        // 
    }

    func urlSession(_ session: URLSession,
                    downloadTask: URLSessionDownloadTask,
                    didFinishDownloadingTo location: URL)
    {
        //
    }

    func urlSession(_ session: URLSession,
                    task: URLSessionTask,
                    didCompleteWithError error: Error?)
    {
        //
    }
}

However, no URLSessionDelegate methods are called.

Normally, delegate methods are not called if you create a task with completion handler - that is not the case, I'm only using URLRequest as parameter when creating a task.

Session's delegate is properly set, and after calling downloadTask?.resume() its state property is running

MyNetworkManager is a singleton, I'm using it like so

MyNetworkManager.instance.download(someURL)

so an instance is definitely retained.

Am I missing something here?


Solution

  • You must conform to the relevant protocols, e.g.:

    extension MyNetworkManager: URLSessionDelegate {
        // this is intentionally blank
    
        // obviously, if you implement any delegate methods for this protocol, put them here
    }
    
    extension MyNetworkManager: URLSessionDownloadDelegate {
        func urlSession(_ session: URLSession,
                        downloadTask: URLSessionDownloadTask,
                        didWriteData bytesWritten: Int64,
                        totalBytesWritten: Int64,
                        totalBytesExpectedToWrite: Int64) {
            print(#function)
        }
    
        func urlSession(_ session: URLSession,
                        downloadTask: URLSessionDownloadTask,
                        didFinishDownloadingTo location: URL) {
            print(#function)
        }
    }
    
    extension MyNetworkManager: URLSessionTaskDelegate {
        func urlSession(_ session: URLSession,
                        task: URLSessionTask,
                        didCompleteWithError error: Error?) {
            print(#function, error ?? "No error")
        }
    }
    

    If you don’t conform to URLSessionDownloadDelegate, it won’t call URLSessionDownloadDelegate methods.