Search code examples
iosdelegatesurlsession

How to use URLSession delegate with custom class


I'm used to making a custom class for URLSession using singleton. So I'm using it with URLSession delegate first time and I'm getting confused. Because delegate method is not called!

Can I know any solution? Did I miss something?

And I just want to check whether making a custom class for URLSession is a good thing?

Here is my code. This is my custom API for URLSession.


import UIKit

class CustomNetworkAPI {
    static let shared = CustomNetworkAPI()
    var session: URLSession?
    private var sessionDataTask: URLSessionDataTask?
    private var sessionDownloadTask: URLSessionDownloadTask?
    var cache: URLCache?
    
    private init() {}
    
    func downloadTaskForImage(_ url: URL, _ completionHandler: @escaping (Result<URL, Error>) -> ()) {
//        print(session.delegate)
        sessionDownloadTask = session?.downloadTask(with: url, completionHandler: { (url, response, error) in
            if let error = error {
                completionHandler(.failure(error))
                return
            }
            
            guard let url = url else {
                completionHandler(.failure(URLRequestError.dataError))
                return
            }
            
            completionHandler(.success(url))
        })
        
        sessionDownloadTask?.resume()
    }
}

And this is sample code(not whole thing) of VC using the api and delegate.

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let api = CustomNetworkAPI.shared
        let config = URLSessionConfiguration.default

        api.session = URLSession(configuration: config, delegate: self, delegateQueue: nil)

        guard let url = URL(string: "...") else { return }
        
        api.downloadTaskForImage(url) { (result) in
            switch result {
            case .success(let url):
                print(url)
            case .failure(let error):
                print(error)
            }
        }
    }
}


extension ViewController: URLSessionDownloadDelegate {
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        print("down load complete")
    }
    
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
        print("ing")
    }
}


Solution

  • I was missing something, which is this quote below that I found in apple docs.

    Your URLSession object doesn’t need to have a delegate. If no delegate is assigned, a system-provided delegate is used, and you must provide a completion callback to obtain the data.

    So I tried to remove the completion handler block, and the delegate method was called.