Hi there =) I was just faced with a design problem where I need to (essentially) do the following:
I want to inject a bit of code on viewWillAppear:
of any UIViewController
subclass that conforms to a protocol MyProtocol
. Explained in code:
protocol MyProtocol { func protocolFunction() { //do cool stuff... } } extension UIViewController where Self: MyProtocol //<-----compilation error { public override class func initialize() { //swizzling stuff switching viewWillAppear(_: Bool) with xxx_viewWillAppear(animated: Bool) } // MARK: - Swizzling func xxx_viewWillAppear(animated: Bool) { self.xxx_viewWillAppear(animated) //invoke APIs from self.protocolFunction() // MyProtocol APIs let viewLoaded = self.isViewLoaded // UIViewController APIs } }
The main issue here is that I need to 2 two things in the UIVIewController
extension:
MyProtocol
and UIViewController
API'sUIViewController
method initialize()
in order to be able to swizzle viewWillAppear:
These 2 capabilities seem incompatible (as of Swift 3) because:
extension UIViewController where Self: MyProtocol
)extension MyProtocol where Self: UIViewController
but we CAN'T override methods from a class in a protocol extension, meaning we can't public override class func initialize()
which is needed for swizzling.So I was wondering if there's somebody out there who can offer a Swifty solution to this problem I'm facing? =)
Thanks in advance!!
Computed Property In Extension However, Swift lets us add computed properties to an extension. For example, extension Circle { // computed property var area: Double { ... } } Here, area is a computed property defined in the extension body.
Protocols let you describe what methods something should have, but don't provide the code inside. Extensions let you provide the code inside your methods, but only affect one data type – you can't add the method to lots of types at the same time.
You can create objects from classes, whereas protocols are just type definitions. Try to think of protocols as being abstract definitions, whereas classes and structs are real things you can create. SPONSORED Want to explore your Swift skill outside of the Apple world?
You were near the solution. Just need to make it other way around. Extend protocol only if its part of UIViewController.
protocol MyProtocol { func protocolFunction() { //do cool stuff... } } extension MyProtocol where Self: UIViewController { public override class func initialize() { //swizzling stuff switching viewWillAppear(_: Bool) with xxx_viewWillAppear(animated: Bool) } // MARK: - Swizzling func xxx_viewWillAppear(animated: Bool) { self.xxx_viewWillAppear(animated) //invoke APIs from self.protocolFunction() // MyProtocol APIs let viewLoaded = self.isViewLoaded // UIViewController APIs } }
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