swift: [SR-3062] Ambiguous selector in Swift 3 for CoreBluetooth delegate methods

Previous ID SR-3062
Radar None
Original Reporter Julien Coudsi (JIRA User)
Type Bug

Attachment: Download

Environment

Xcode 8.1, Swift 3

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, DiagnosticsQoI, TypeChecker
Assignee None
Priority Medium

md5: 36322bb25de0649b7703eec4d6a684e0

Issue Description:

I need to declare a selector on CBPeripheralDelegate functions, for example :

func peripheral(peripheral: CBPeripheral, didUpdateValueForCharacteristic characteristic: CBCharacteristic, error: NSError?)

In Swift3, it is renamed to peripheral(_: didUpdateValueFor:error), and it is same as the func peripheral(peripheral: CBPeripheral, didUpdateValueForDescriptor descriptor: CBDescriptor, error: NSError?)

So, when I try to define a selector like this :

#selector(CBPeripheralDelegate.peripheral(_:didUpdateValueFor:error:))

It will cause a compile error: ambiguous use.

So I try to define with the parameters types :

#selector(((CBPeripheralDelegate.peripheral(_:didUpdateValueFor:error:)) as (CBPeripheralDelegate) -> (CBPeripheral, CBCharacteristic, NSError?) -> Void)

I try also :

#selector(((CBPeripheralDelegate.peripheral(_:didUpdateValueFor:error:)) as (CBPeripheralDelegate) -> (CBPeripheral, CBCharacteristic, NSError) -> Void)

But it failed either.

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 26 (10 by maintainers)

Most upvoted comments

@freak4pc @kennyevo It looks like getting the function as a value for an optional protocol method changed from being an optional function value to being a non-optional function that takes the instance and returns the instance function as an optional, so the position of the parentheses has to change. The following compiles for me (previous version shown commented out for comparison):

static let decidePolicyNavigationResponse: Selector = 
// #selector(WKNavigationDelegate.webView(_:decidePolicyFor:decisionHandler:) as ((WKNavigationDelegate) -> (WKWebView, WKNavigationResponse, @escaping (WKNavigationResponsePolicy) -> Void) -> Void)?)
   #selector(WKNavigationDelegate.webView(_:decidePolicyFor:decisionHandler:) as (WKNavigationDelegate) -> ((WKWebView, WKNavigationResponse, @escaping (WKNavigationResponsePolicy) -> Void) -> Void)?)
static let decidePolicyNavigationAction: Selector = 
// #selector(WKNavigationDelegate.webView(_:decidePolicyFor:decisionHandler:) as ((WKNavigationDelegate) -> (WKWebView, WKNavigationAction, @escaping(WKNavigationActionPolicy) -> Void) -> Void)?)
   #selector(WKNavigationDelegate.webView(_:decidePolicyFor:decisionHandler:) as (WKNavigationDelegate) -> ((WKWebView, WKNavigationAction, @escaping(WKNavigationActionPolicy) -> Void) -> Void)?)

In Swift 5.7, the type of an unbound reference to an optional method was fixed and changed from ((x) -> (y) -> z)? to (x) -> ((y) -> z)?. Please read earlier comments for more details.

Sorry for the huge bump but seems like this just became an issue again in Xcode 14. Should I just open a new bug for it?

The workaround no longer works, too.

image

There are a few open source projects that use this, we also have some internal stuff that uses it and we won’t be moving everyone to Xcode 14 immediately, for obvious reasons 😃

Thanks you for the quick response 🙏

So would this have to live inside a compiler directive?

Yeah, you would have to branch out on #if swift(>=5.7) to make older compilers happy. Where do these declarations come from?

It looks like getting the function as a value for an optional protocol method changed from being an optional function value to being a non-optional function that takes the instance and returns the instance function as an optional

Yes, this is mentioned in the change log. Unbound references to optional protocol methods should be of a non-optional function type that takes an instance and returns an optional function type, i.e. (P) -> ((args) -> result)?. It was a bug that the entire type was getting wrapped in an optional. Here’s a related twitter thread.