Description:
I'm noticing that when using the completion handler variant of URLSession.dataTask(with:), the delegate method urlSession(_:dataTask:didReceive:) is not called—even though a delegate is set when creating the session.
Here's a minimal reproducible example:
✅ Case where delegate method is called:
class CustomSessionDelegate: NSObject, URLSessionDataDelegate {
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
print("✅ Delegate method called: Data received")
}
}
let delegate = CustomSessionDelegate()
let session = URLSession(configuration: .default, delegate: delegate, delegateQueue: nil)
let request = URLRequest(url: URL(string: "https://httpbin.org/get")!)
let task = session.dataTask(with: request) // ✅ No completion handler
task.resume()
In this case, the delegate method didReceive is called as expected.
❌ Case where delegate method is NOT called:
class CustomSessionDelegate: NSObject, URLSessionDataDelegate {
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
print("❌ Delegate method NOT called")
}
}
let delegate = CustomSessionDelegate()
let session = URLSession(configuration: .default, delegate: delegate, delegateQueue: nil)
let request = URLRequest(url: URL(string: "https://httpbin.org/get")!)
let task = session.dataTask(with: request) { data, response, error in
print("Completion handler called")
}
task.resume()
Here, the completion handler is executed, but the delegate method didReceive is never called.
Notes:
I’ve verified this behavior on iOS 16, 17, and 18.
Other delegate methods such as urlSession(_:task:didFinishCollecting:) do get called with the completion handler API.
This happens regardless of whether swizzling or instrumentation is involved — the issue is reproducible even with direct method implementations.
Questions:
Is this the expected behavior (i.e., delegate methods like didReceive are skipped when a completion handler is used)?
If yes, is there any official documentation that explains this?
Is there a recommended way to ensure delegate methods are invoked, even when using completion handler APIs?
Thanks in advance!
Selecting any option will automatically load the page