13

After I updated to latest Xcode 8, I get this error:

Cannot inherit from non-open class ‘WDBaseViewController’ outside of its defining module

My class is declared like this

public class ProfileViewController: WDBaseViewController {
}

But I didn’t change the framework.

Yann Bodson
  • 1,634
  • 1
  • 17
  • 29
  • The base class `WDBaseViewController` needs to be defined as `open` instead of `public` in the framework you are using. – Yann Bodson Aug 22 '16 at 06:10
  • See also [What is the 'open' keyword in Swift?](http://stackoverflow.com/questions/38947101/what-is-the-open-keyword-in-swift), and the Xcode 8 beta 6 Release Notes. – Martin R Aug 22 '16 at 06:49
  • Yes, I found it. Thanks. –  Aug 22 '16 at 07:16

1 Answers1

40

Short answer:

To be able to subclass it, the base class WDBaseViewController needs to be defined as open instead of public in the framework you are using.

open class WDBaseViewController {
    ...
}

If it’s an internal framework you can do it yourself, otherwise you will have to wait for the author to support Swift 3.

Long answer:

Swift 3 is bringing significant changes to access control.

Swift 2 only had 3 access levels:

  • private: entities are available only from within the source file where they are defined.
  • internal: entities are available to the entire module that includes the definition.
  • public: entities are intended for use as API, and can be accessed by any file that imports the module.

Swift 3 is adding 2 more access levels (open and fileprivate) and changing the meaning of private:

  • private: symbol visible within the current declaration only.
  • fileprivate: symbol visible within the current file.
  • internal: symbol visible within the current module.
  • public: symbol visible outside the current module.
  • open: for class or function to be subclassed or overridden outside the current module.
Yann Bodson
  • 1,634
  • 1
  • 17
  • 29
  • Hi Yann, which access level to choose is also driven by testing requirements. When you use '@testable import' in unit tests it does not allow access to private or fileprivate symbols. It does open up access to internal symbols – chrisoneiota Nov 23 '18 at 11:14