Swift extension for selected class instance
Define a protocol that will serve as a selection, wether the extensions should be available or not:
protocol UIViewExtensions { }
then define an extension for the protocol, but only for subclasses of UIView
(the other way around won't work):
extension UIViewExtensions where Self: UIView {
func testFunc() -> String { return String(tag) }
}
A class that is defined to have the protocol will also have the extension:
class A: UIView, UIViewExtensions { }
A().testFunc() //has the extension
And if it is not defined to have the protocol, it will also not have the extension:
class B: UIView {}
B().testFunc() //execution failed: MyPlayground.playground:17:1: error: value of type 'B' has no member 'testFunc'
UPDATE
Since protocol extensions don't do class polymorphism, if you need to override functions, the only thing I can think of is to subclass:
class UIViewWithExtensions: UIView {
override func canBecomeFocused() -> Bool { return true }
}
UIViewWithExtensions().canBecomeFocused() // returns true
this could also be combined with the extension, but I don't think it would still make much sense anymore.
Swift: Viewing full class API including extensions
I would say offhand that there's no good way to do it. You'd think that the Symbol Navigator would be the way, but it seems to know nothing of Swift extensions (as opposed to Objective-C categories, which it does know about). Being created entirely with the Objective-C family of languages in mind, Xcode has not yet caught up with the existence and nature of Swift.
Using 'self' in class extension functions in Swift
Using the approach from How can I create instances of managed object subclasses in a NSManagedObject Swift extension?
you can define a generic helper method which infers the type of self
from the calling context:
extension UIView {
class func instantiateFromNib() -> Self? {
return instantiateFromNibHelper()
}
private class func instantiateFromNibHelper<T>() -> T? {
let topLevelObjects = NSBundle.mainBundle().loadNibNamed("CustomViews", owner: nil, options: nil)
for topLevelObject in topLevelObjects {
if let object = topLevelObject as? T {
return object
}
}
return nil
}
}
This compiles and works as expected in my quick test. IfMyCustomView
is your UIView
subclass then
if let customView = MyCustomView.instantiateFromNib() {
// `customView` is a `MyCustomView`
// ...
} else {
// Not found in Nib file
}
gives you an instance of MyCustomView
, and the type is
inferred automatically.
Update for Swift 3:
extension UIView {
class func instantiateFromNib() -> Self? {
return instantiateFromNibHelper()
}
private class func instantiateFromNibHelper<T>() -> T? {
if let topLevelObjects = Bundle.main.loadNibNamed("CustomViews", owner: nil, options: nil) {
for topLevelObject in topLevelObjects {
if let object = topLevelObject as? T {
return object
}
}
}
return nil
}
}
Extensions in my own custom class
In the case of a class that you create from scratch extensions are a powerful type of documentation through structure. You put the core of your class in the initial definition and then add on extensions to provide additional features. For example, adding adherence to a protocol. It provides locality to the contained code:
struct Foo {
let age: Int
}
extension Foo: CustomStringConvertible {
var description:String { return "age: \(age)" }
}
Could I have put the protocol and computed property in the struct declaration? Absolutely but when you have more than one or two properties it starts to get messy and difficult to read. It's easier to create bugs if the code isn't clean and readable. Using extensions is a great way to stave off the difficulties that come with complexity.
Can a Swift class be extended multiple times with the same methods?
Overriding a single protocol method twice in 2 separate extensions wouldn't work, because the protocol method names would collide. Once compiled, they're all just methods on the same class. With that in mind, perhaps put all the protocol methods in their own extension & call them from within the other ones?
The following could be one general option. Could get messy if you decide to keep adding additional extension functionality.
class baseClass {
//stuff
}
extension baseClass: myProtocol {
override func myProtocolMethod(args) -> returnType {
//Repeat this in a separate extension & your method names collide
var status: Bool
//protocol method code sets status as appropriate...
return status = true ? optOne(status) : optTwo(status)
}
func optOne(status:Bool) -> returnType{
//do the 'true' thing
return returnType
}
func optTwo(status:Bool) -> returnType{
//do the 'false' thing
return returnType
}
}
extension baseClass {
var oneExtension = myProtocolMethod(someArg)
}
extension baseClass {
var twoExtension = myProtocolMethod(someArg)
}
Related Topics
Retrieving Keys from Geofire Within Radius in Swift
Changing Value in Nested Dictionary in Swift
Select All Text in Textfield Upon Click Swiftui
Swift - Class Method Which Must Be Overridden by Subclass
How to Benchmark Swift Code Execution
How to Make Nsattributedstring Codable Compliant
Property Observers for Uiview Bounds and Frame React Differently
How to Get Unmanaged Object from Realm Query in Swift
How to Filter on an Array of Objects in Swift
Using Swift Library in Xamarin
Detecting If Wifi or Bluetooth Is Turned on or Off by the User
Clgeocoder in Swift - Unable to Return String When Using Reversegeocodelocation
Testing an Executable with Swift
Why Does Swift Return an Unexpected Pointer When Converting an Optional String into an Unsafepointer
Swift 3:Issue with Avvideocompositioncoreanimationtool to Add Watermark on Video
Convert Bar Chart to a Grouped Bar Chart with Danielgindi/Ios-Charts and Swift