With introduction of open
keyword in Swift 3.0 (What is the 'open' keyword in Swift?).
Note: Limited to extensions on NSObject
derived classes or @objc
attributed method/properties.
Code which declared and used public
(class
) methods/properties in extension across modules/frameworks broke, as public
is no longer means 'overridable' outside of defining module.
Example:
public extension UIManagedDocument {
public class func primaryDocumentName() -> String {
return "Document"
}
public class func primaryStoreURL() -> URL {
let documentsURL = FileManager.default.userDocumentsURL
return URL(fileURLWithPath: self.primaryDocumentName(), isDirectory: false, relativeTo: documentsURL)
}
public class func primaryModelName() -> String? {
return "Model"
}
}
open
keyword (you can't write open extension NSObject
as well as open func Method()
)Question: Is there workaround to be able override extension provided methods/properties across modules/frameworks?
Open is an access level, was introduced to impose limitations on class inheritance on Swift. This means that the open access level can only be applied to classes and class members.
Open — This is where you can access all data members and member functions within the same module(target) and outside of it. You can subclass or override outside the module(target). Public — This is the same as open, the only difference is you can't subclass or override outside the module(target).
Open - same as public, only difference is you can subclass or override outside the module. Fileprivate - As the name say's, data members and member functions are accessible within the same file. Private - This is where you can have access within the scope of function body or class.
Unless I am mistaken, you can declare the extension methods as
open
in your framework if you just omit the public
keyword
in the extension declaration:
extension UIManagedDocument {
open class func primaryDocumentName() -> String {
return "Document"
}
// ...
}
And then (for NSObject
subclasses or @objc
members) you can override the method
in your custom subclass in the main application (or in any module):
class MyManagedDocument: UIManagedDocument {
override class func primaryDocumentName() -> String {
return "MyDocument"
}
// ...
}
Protocol example:
protocol PrimaryDocument {
static func primaryDocumentName() -> String
static func primaryStoreURL() -> URL
static func primaryModelName() -> String?
}
extension UIManagedDocument : PrimaryDocument {
open class func primaryDocumentName() -> String {
return "Document"
}
open class func primaryStoreURL() -> URL {
let documentsURL = FileManager.default.userDocumentsURL
return URL(fileURLWithPath: self.primaryDocumentName(), isDirectory: false, relativeTo: documentsURL)
}
open class func primaryModelName() -> String? {
return "Model"
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With