2 Replies
      Latest reply: Dec 14, 2016 1:27 PM by 610 RSS
      610 Level 1 Level 1 (0 points)

        I'm in the process of converting a project to Swift 3, and I've run into a weird conflict with the automatic renaming of Objective-C methods into Swift.

        • I have a Objective-C protocol Foo that declares a required method -(void)clearListSelection.
        • I have an Objective-C class FooController with a public method matching that selector.
        • I have a Swift class BarController that inherits form FooController, and declares conformance to the Foo protocol.

         

        Previously, this was all fine (as it would be if all parts were Objective-C). Now, the compiler "helpfully" renames the required method to clearSelection() in Swift. Thus:

        • BarController no longer conforms to Foo, because it doesn't implement the required method.
        • I can't add a method clearListSelection() to BarController, because the compiler says I need to override the inherited method.
        • Once I add that keyword, the compiler complains that the method has been renamed.
        • If I try to override clearSelection(), the compiler complains that there is no such method in the superclass.
        • And if I take off the override, it tells me the method has an Objective-C selector that conflicts with a method from its superclass.

         

        So, the compiler seems to be smart enough to prevent me from taking a number of bad paths, but not smart enough to recognize the good path. It's hard for me to tell whether this is a bug, or something Swift 3 is deliberately making impossible.

         

        It does appear to be the case that I can add an NS_SWIFT_NAME attribute to the protocol declaration to get the compiler to stop "fixing" the name. But this still feels wrong to me.

        • Re: Protocol conformance Catch-22
          eskimo Apple Staff Apple Staff (5,995 points)

          Now, the compiler "helpfully" renames the required method to clearSelection() in Swift.

          This is the bit that’s confusing me.  I created a new project (Xcode 8.2) and added an Objective-C header that looks like this:

          @protocol Foo <NSObject>
          
          @required
          
          - (void)clearListSection;
          
          @end
          

          I then implemented that in Swift like this:

          class FooController : NSObject, Foo {
              func clearListSection() {
              }
          }
          

          There’s no renaming going on, and I’m not sure why there would be renaming going on in your project.

          If you create a minimal test project as I’ve described above, do you still see the problem?

          Share and Enjoy

          Quinn “The Eskimo!”
          Apple Developer Relations, Developer Technical Support, Core OS/Hardware
          let myEmail = "eskimo" + "1" + "@apple.com"

            • Re: Protocol conformance Catch-22
              610 Level 1 Level 1 (0 points)

              There's a layer in our code that you've skipped in your example: the Swift class declares conformance, but inherits the method from an Objective-C superclass. But I have not yet tried to create a minimal test case, so there could be something else going on, too.