How to unambiguously refer to a symbol defined in an extension in third party module?

I have a project which uses Reachability and this code to receive notifications:

NotificationCenter.default.addObserver(
  self,
  selector: #selector(didReceiveReachabilityChangedNotification),
  name: .reachabilityChanged,
  object: nil
)

However, after upgrading another framework this started to give "ambiguous use" errors. It turns out that this third party framework has started to use Reachability internally and somehow is reexporting its symbols. I don't want to rely on whatever version they are using internally, and replace this:

import Reachability
// import SomeFramework.Reachability

They are both basically doing this:

public extension Notification.Name {
    static let reachabilityChanged = Notification.Name("reachabilityChanged")
}

When looking at the symbols using nm -g SomeFramework, and demangling the result, I'm getting:

$sSo18NSNotificationNamea13SomeFrameworkE19reachabilityChangedABvpZ ---> static (extension in SomeFramework):__C.NSNotificationName.reachabilityChanged : __C.NSNotificationName

Using either Reachability.Notification.Name.reachabilityChanged or Reachability.NSNotificationName.reachabilityChanged to refer to the value doesn't work.

1 Like

Does it work if you create a separate source file that imports only Reachability and defines your own symbol that's an alias of it, and then refer to that new name in any files that import the framework that's reëxporting the symbol?

import Reachability

public extension Notification.Name {
  static let myReachabilityChangedWorkaround = Notification.Name.reachabilityChanged
}

I might be wrong but I don't think the other framework's symbol, even for extensions, should be visible in a source file that only imports Reachability.

Edit: vvv Thanks for the correction :frowning_face:

They shouldn't be, but they are. You have to have an entirely separate module to avoid extension member pollution today.

As to the original question, Swift needs a way to disambiguate extension members by module and currently doesn't have one, something like Foo.HelperFramework☃︎bar (or in this case name: .Reachability☃︎reachabilityChanged). Syntax here obviously needs work. :-)

4 Likes

This would be super awesome, I’ve been wanting this for years.

Maybe something like Foo.(HelperFramework)bar would do. Concise and simple.