Cannot implement NSURLSessionDownloadDelegate


(Sebastian Hagedorn) #1

I have started migrating a Swift 2.2 project to Swift 3.0 using the latest dev snapshot (16 March 2016) and Xcode 7.3.

I have an existing class (and have verified the same behaviour in a new, isolated test project) that declares to conform to NSURLSessionDownloadDelegate (and inherits from NSObject). However, I cannot satisfy the compiler as I get the following error:

.../SessionDel.swift:11:7: Type 'MyDelegate' does not conform to protocol 'NSURLSessionDownloadDelegate'

.../Foundation.NSURLSessionDownloadDelegate:3:17: Protocol requires function 'urlSession(_:downloadTask:didFinishDownloadingTo:)' with type '(NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingTo: NSURL) -> Void’

.../SessionDel.swift:13:10: Objective-C method 'urlSession:downloadTask:didFinishDownloadingTo:' provided by method 'urlSession(_:downloadTask:didFinishDownloadingTo:)' does not match the requirement's selector ('URLSession:downloadTask:didFinishDownloadingToURL:’)

The signature that Xcode’s autocompletion suggests is this:

func urlSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingTo location: NSURL)

…which is slightly different from the one in the error message (the first parameter), but neither works. I’ve also tried several variants with regard to capitalization and truncation of parameter names, but cannot get this to compile. Is this a known/temporary issue in the current snapshot, or should I file a bug report?

Cheers
Sebastian


(Jordan Rose) #2

Note the error message carefully: the method you implemented has the right name in Swift, but "does not match the requirement's selector". You can manually control the selector using the 'objc' attribute, i.e. `@objc(URLSession:downloadTask:didFinishDownloadingToURL:)`.

Doug is looking at inferring selector names from the protocols you conform to, though it'll probably be limited in some way so that we don't do a huge amount of extra work.

Jordan

···

On Mar 22, 2016, at 8:49, Sebastian Hagedorn via swift-users <swift-users@swift.org> wrote:

I have started migrating a Swift 2.2 project to Swift 3.0 using the latest dev snapshot (16 March 2016) and Xcode 7.3.

I have an existing class (and have verified the same behaviour in a new, isolated test project) that declares to conform to NSURLSessionDownloadDelegate (and inherits from NSObject). However, I cannot satisfy the compiler as I get the following error:

.../SessionDel.swift:11:7: Type 'MyDelegate' does not conform to protocol 'NSURLSessionDownloadDelegate'

.../Foundation.NSURLSessionDownloadDelegate:3:17: Protocol requires function 'urlSession(_:downloadTask:didFinishDownloadingTo:)' with type '(NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingTo: NSURL) -> Void’

.../SessionDel.swift:13:10: Objective-C method 'urlSession:downloadTask:didFinishDownloadingTo:' provided by method 'urlSession(_:downloadTask:didFinishDownloadingTo:)' does not match the requirement's selector ('URLSession:downloadTask:didFinishDownloadingToURL:’)

The signature that Xcode’s autocompletion suggests is this:

func urlSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingTo location: NSURL)

…which is slightly different from the one in the error message (the first parameter), but neither works. I’ve also tried several variants with regard to capitalization and truncation of parameter names, but cannot get this to compile. Is this a known/temporary issue in the current snapshot, or should I file a bug report?


(Douglas Gregor) #3

This is <rdar://problem/25159872> Unable to make swift class conform to certain obj-c protocol.

  - Doug

···

On Mar 22, 2016, at 9:55 AM, Jordan Rose <jordan_rose@apple.com> wrote:

On Mar 22, 2016, at 8:49, Sebastian Hagedorn via swift-users <swift-users@swift.org> wrote:

I have started migrating a Swift 2.2 project to Swift 3.0 using the latest dev snapshot (16 March 2016) and Xcode 7.3.

I have an existing class (and have verified the same behaviour in a new, isolated test project) that declares to conform to NSURLSessionDownloadDelegate (and inherits from NSObject). However, I cannot satisfy the compiler as I get the following error:

.../SessionDel.swift:11:7: Type 'MyDelegate' does not conform to protocol 'NSURLSessionDownloadDelegate'

.../Foundation.NSURLSessionDownloadDelegate:3:17: Protocol requires function 'urlSession(_:downloadTask:didFinishDownloadingTo:)' with type '(NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingTo: NSURL) -> Void’

.../SessionDel.swift:13:10: Objective-C method 'urlSession:downloadTask:didFinishDownloadingTo:' provided by method 'urlSession(_:downloadTask:didFinishDownloadingTo:)' does not match the requirement's selector ('URLSession:downloadTask:didFinishDownloadingToURL:’)

The signature that Xcode’s autocompletion suggests is this:

func urlSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingTo location: NSURL)

…which is slightly different from the one in the error message (the first parameter), but neither works. I’ve also tried several variants with regard to capitalization and truncation of parameter names, but cannot get this to compile. Is this a known/temporary issue in the current snapshot, or should I file a bug report?

Note the error message carefully: the method you implemented has the right name in Swift, but "does not match the requirement's selector". You can manually control the selector using the 'objc' attribute, i.e. `@objc(URLSession:downloadTask:didFinishDownloadingToURL:)`.

Doug is looking at inferring selector names from the protocols you conform to, though it'll probably be limited in some way so that we don't do a huge amount of extra work.


(Sebastian Hagedorn) #4

Thanks for looking into it and the quick fix, much appreciated. I’d assume this issue will come up many many times once the first Xcode beta ships with Swift 3.0.

···

On 22 Mar 2016, at 17:56, Douglas Gregor <dgregor@apple.com> wrote:

On Mar 22, 2016, at 9:55 AM, Jordan Rose <jordan_rose@apple.com> wrote:

On Mar 22, 2016, at 8:49, Sebastian Hagedorn via swift-users <swift-users@swift.org> wrote:

I have started migrating a Swift 2.2 project to Swift 3.0 using the latest dev snapshot (16 March 2016) and Xcode 7.3.

I have an existing class (and have verified the same behaviour in a new, isolated test project) that declares to conform to NSURLSessionDownloadDelegate (and inherits from NSObject). However, I cannot satisfy the compiler as I get the following error:

.../SessionDel.swift:11:7: Type 'MyDelegate' does not conform to protocol 'NSURLSessionDownloadDelegate'

.../Foundation.NSURLSessionDownloadDelegate:3:17: Protocol requires function 'urlSession(_:downloadTask:didFinishDownloadingTo:)' with type '(NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingTo: NSURL) -> Void’

.../SessionDel.swift:13:10: Objective-C method 'urlSession:downloadTask:didFinishDownloadingTo:' provided by method 'urlSession(_:downloadTask:didFinishDownloadingTo:)' does not match the requirement's selector ('URLSession:downloadTask:didFinishDownloadingToURL:’)

The signature that Xcode’s autocompletion suggests is this:

func urlSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingTo location: NSURL)

…which is slightly different from the one in the error message (the first parameter), but neither works. I’ve also tried several variants with regard to capitalization and truncation of parameter names, but cannot get this to compile. Is this a known/temporary issue in the current snapshot, or should I file a bug report?

Note the error message carefully: the method you implemented has the right name in Swift, but "does not match the requirement's selector". You can manually control the selector using the 'objc' attribute, i.e. `@objc(URLSession:downloadTask:didFinishDownloadingToURL:)`.

Doug is looking at inferring selector names from the protocols you conform to, though it'll probably be limited in some way so that we don't do a huge amount of extra work.

This is <rdar://problem/25159872> Unable to make swift class conform to certain obj-c protocol.

  - Doug


(Charles Lane) #5

I have the same problem except it’s with the UISearchResultsUpdating protocol. I read Jordan’s reply with the workaround but I’m not familiar enough with OBJC to implement it. Could you possibly show me the correct form for the following:

func updateSearchResults(for searchController: UISearchController) {
        
    }

How do I format that using the ‘objc’ attribute to make it satisfy the protocol requirements? I know that Apple will fix this soon, but I’m curious…..

Thanks,
Chuck Lane


(Douglas Gregor) #6

Thanks for looking into it and the quick fix, much appreciated. I’d assume this issue will come up many many times once the first Xcode beta ships with Swift 3.0.

We are not going to ship an Xcode to external customers (even as a beta) without a solution to this issue. The compiler improvements are scheduled for M4.

  - Doug

···

On Mar 23, 2016, at 2:13 AM, Sebastian Hagedorn <sebastian@iosphere.de> wrote:

On 22 Mar 2016, at 17:56, Douglas Gregor <dgregor@apple.com> wrote:

On Mar 22, 2016, at 9:55 AM, Jordan Rose <jordan_rose@apple.com> wrote:

On Mar 22, 2016, at 8:49, Sebastian Hagedorn via swift-users <swift-users@swift.org> wrote:

I have started migrating a Swift 2.2 project to Swift 3.0 using the latest dev snapshot (16 March 2016) and Xcode 7.3.

I have an existing class (and have verified the same behaviour in a new, isolated test project) that declares to conform to NSURLSessionDownloadDelegate (and inherits from NSObject). However, I cannot satisfy the compiler as I get the following error:

.../SessionDel.swift:11:7: Type 'MyDelegate' does not conform to protocol 'NSURLSessionDownloadDelegate'

.../Foundation.NSURLSessionDownloadDelegate:3:17: Protocol requires function 'urlSession(_:downloadTask:didFinishDownloadingTo:)' with type '(NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingTo: NSURL) -> Void’

.../SessionDel.swift:13:10: Objective-C method 'urlSession:downloadTask:didFinishDownloadingTo:' provided by method 'urlSession(_:downloadTask:didFinishDownloadingTo:)' does not match the requirement's selector ('URLSession:downloadTask:didFinishDownloadingToURL:’)

The signature that Xcode’s autocompletion suggests is this:

func urlSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingTo location: NSURL)

…which is slightly different from the one in the error message (the first parameter), but neither works. I’ve also tried several variants with regard to capitalization and truncation of parameter names, but cannot get this to compile. Is this a known/temporary issue in the current snapshot, or should I file a bug report?

Note the error message carefully: the method you implemented has the right name in Swift, but "does not match the requirement's selector". You can manually control the selector using the 'objc' attribute, i.e. `@objc(URLSession:downloadTask:didFinishDownloadingToURL:)`.

Doug is looking at inferring selector names from the protocols you conform to, though it'll probably be limited in some way so that we don't do a huge amount of extra work.

This is <rdar://problem/25159872> Unable to make swift class conform to certain obj-c protocol.

  - Doug


(Sebastian Hagedorn) #7

You’d have to add @objc(updateSearchResultsForSearchController:) to it.

If you’re having issues in other places of your code, you can easily get the ObjC selector form by looking into the online docs, e.g.:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UISearchResultsUpdating_ClassRef/index.html

…and choose Objective-C as your preferred language in the top panel.

While this works well enough for required protocol methods, the bigger problem is with optional methods, as the compiler won’t complain if it doesn’t find a matching Swift method, it just won’t ever be called.

···

On 31 Mar 2016, at 00:34, Charles Lane <clane_47@bellsouth.net> wrote:

I have the same problem except it’s with the UISearchResultsUpdating protocol. I read Jordan’s reply with the workaround but I’m not familiar enough with OBJC to implement it. Could you possibly show me the correct form for the following:

func updateSearchResults(for searchController: UISearchController) {
        
    }

How do I format that using the ‘objc’ attribute to make it satisfy the protocol requirements? I know that Apple will fix this soon, but I’m curious…..

Thanks,
Chuck Lane


(Sebastian Hagedorn) #8

Just wanted to follow up as I’ve stumbled over a new bug related to this. It seems that the inferred selectors are mostly correct, unless the protocol conformance is declared in a superclass (it may have to do with a separate file, too). I’ve filed this as rdar://27348369.

Thanks for looking into it!

Sebastian

···

On 23 Mar 2016, at 10:13, Sebastian Hagedorn <sebastian@iosphere.de> wrote:

Thanks for looking into it and the quick fix, much appreciated. I’d assume this issue will come up many many times once the first Xcode beta ships with Swift 3.0.

On 22 Mar 2016, at 17:56, Douglas Gregor <dgregor@apple.com> wrote:

On Mar 22, 2016, at 9:55 AM, Jordan Rose <jordan_rose@apple.com> wrote:

On Mar 22, 2016, at 8:49, Sebastian Hagedorn via swift-users <swift-users@swift.org> wrote:

I have started migrating a Swift 2.2 project to Swift 3.0 using the latest dev snapshot (16 March 2016) and Xcode 7.3.

I have an existing class (and have verified the same behaviour in a new, isolated test project) that declares to conform to NSURLSessionDownloadDelegate (and inherits from NSObject). However, I cannot satisfy the compiler as I get the following error:

.../SessionDel.swift:11:7: Type 'MyDelegate' does not conform to protocol 'NSURLSessionDownloadDelegate'

.../Foundation.NSURLSessionDownloadDelegate:3:17: Protocol requires function 'urlSession(_:downloadTask:didFinishDownloadingTo:)' with type '(NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingTo: NSURL) -> Void’

.../SessionDel.swift:13:10: Objective-C method 'urlSession:downloadTask:didFinishDownloadingTo:' provided by method 'urlSession(_:downloadTask:didFinishDownloadingTo:)' does not match the requirement's selector ('URLSession:downloadTask:didFinishDownloadingToURL:’)

The signature that Xcode’s autocompletion suggests is this:

func urlSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingTo location: NSURL)

…which is slightly different from the one in the error message (the first parameter), but neither works. I’ve also tried several variants with regard to capitalization and truncation of parameter names, but cannot get this to compile. Is this a known/temporary issue in the current snapshot, or should I file a bug report?

Note the error message carefully: the method you implemented has the right name in Swift, but "does not match the requirement's selector". You can manually control the selector using the 'objc' attribute, i.e. `@objc(URLSession:downloadTask:didFinishDownloadingToURL:)`.

Doug is looking at inferring selector names from the protocols you conform to, though it'll probably be limited in some way so that we don't do a huge amount of extra work.

This is <rdar://problem/25159872> Unable to make swift class conform to certain obj-c protocol.

  - Doug


(Douglas Gregor) #9

Just wanted to follow up as I’ve stumbled over a new bug related to this. It seems that the inferred selectors are mostly correct, unless the protocol conformance is declared in a superclass (it may have to do with a separate file, too). I’ve filed this as rdar://27348369.

Thanks for looking into it!

Thanks for the reminder! We’ll try to get to it.

  - Doug

···

On Jul 14, 2016, at 7:07 AM, Sebastian Hagedorn <sebastian@iosphere.de> wrote:

Sebastian

On 23 Mar 2016, at 10:13, Sebastian Hagedorn <sebastian@iosphere.de> wrote:

Thanks for looking into it and the quick fix, much appreciated. I’d assume this issue will come up many many times once the first Xcode beta ships with Swift 3.0.

On 22 Mar 2016, at 17:56, Douglas Gregor <dgregor@apple.com> wrote:

On Mar 22, 2016, at 9:55 AM, Jordan Rose <jordan_rose@apple.com> wrote:

On Mar 22, 2016, at 8:49, Sebastian Hagedorn via swift-users <swift-users@swift.org> wrote:

I have started migrating a Swift 2.2 project to Swift 3.0 using the latest dev snapshot (16 March 2016) and Xcode 7.3.

I have an existing class (and have verified the same behaviour in a new, isolated test project) that declares to conform to NSURLSessionDownloadDelegate (and inherits from NSObject). However, I cannot satisfy the compiler as I get the following error:

.../SessionDel.swift:11:7: Type 'MyDelegate' does not conform to protocol 'NSURLSessionDownloadDelegate'

.../Foundation.NSURLSessionDownloadDelegate:3:17: Protocol requires function 'urlSession(_:downloadTask:didFinishDownloadingTo:)' with type '(NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingTo: NSURL) -> Void’

.../SessionDel.swift:13:10: Objective-C method 'urlSession:downloadTask:didFinishDownloadingTo:' provided by method 'urlSession(_:downloadTask:didFinishDownloadingTo:)' does not match the requirement's selector ('URLSession:downloadTask:didFinishDownloadingToURL:’)

The signature that Xcode’s autocompletion suggests is this:

func urlSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingTo location: NSURL)

…which is slightly different from the one in the error message (the first parameter), but neither works. I’ve also tried several variants with regard to capitalization and truncation of parameter names, but cannot get this to compile. Is this a known/temporary issue in the current snapshot, or should I file a bug report?

Note the error message carefully: the method you implemented has the right name in Swift, but "does not match the requirement's selector". You can manually control the selector using the 'objc' attribute, i.e. `@objc(URLSession:downloadTask:didFinishDownloadingToURL:)`.

Doug is looking at inferring selector names from the protocols you conform to, though it'll probably be limited in some way so that we don't do a huge amount of extra work.

This is <rdar://problem/25159872> Unable to make swift class conform to certain obj-c protocol.

  - Doug