How to get the right selector from URLSession.dataTask(with:completionHandler:) on Xcode?

On Xcode 11.6 (11E708) (Swift 5.2.4) the compiler gets confused and shows the error below:

Cannot convert value of type '(URLSession) -> (URL, @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask' to type '(URLSession) -> (URLRequest, @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask' in coercion

I'm trying to get the selector like follows, but the compiler still tries to convert to the version with URL instead:

let selector = #selector(URLSession.dataTask(with:completionHandler:) as (URLSession) -> (URLRequest, @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask)

enter image description here

This is the output of xcrun swift -version

Apple Swift version 5.2.4 (swiftlang-1103.0.32.9 clang-1103.0.32.53)
Target: x86_64-apple-darwin19.2.0

This works on my machine. Using Xcode 11.6 I created a new command-line tool project, changed main.swift to the below, and it compiles just fine.

import Foundation

func main() {
    let selector = #selector(URLSession.dataTask(with:completionHandler:) as (URLSession) -> (URLRequest, @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask)
    print(selector)
}

main()

When I run it, it prints:

dataTaskWithRequest:completionHandler:

I suspect there’s something about your context that’s messing things up, and it’s hard to say what without more context.


Having said that, please don’t swizzle methods on classes you don’t ‘own’. NSURLSession was not designed to be patched in this way and, in my experience, patches like this tend to cause problems in the long term. If you’re lucky, they’re problems like this one, that show up at compile time. If you’re less lucky, they show up at runtime.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

Thanks for taking a look at it. Did you run the code from Xcode or was it from the Terminal app? I'm able to run the code from the command line fine, so I'm suspecting it could be related to my project settings, or perhaps to Xcode using a different version of the static analyzer. FYI, I'm using swizzling to test a class that uses URLSession, so it should be perfectly fine since production code will not be using the patched class.

Did you run the code from Xcode or was it from the Terminal app?

Quoting myself here:

Using Xcode 11.6 I created a new command-line tool project

I recommend that you do the same, just to confirm that your Xcode and my Xcode agree on the basics. After that you can start diff’ing your working command-line tool project against your failing main project.

Note My best guess here is that you’ve added an extension to URLSession in your main project and it’s that extension that’s triggering the failure.


FYI, I'm using swizzling to test a class that uses URLSession, so it
should be perfectly fine since production code will not be using the
patched class.

That’s great news, although personally I avoid this complexity by adding a hook to the code under test that lets by substitute my test network subsystem in place of the real one.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple

1 Like

I added a command line tool target to my project with the snippet to try the selector and it compiles ok. Now I'm adding new targets to replace the old ones generated by the swift command line tool. It seems to me it's swift CLI build settings that were given to the project the ones giving the error I mentioned. Thanks for your suggestion.