Swift extension of a class ONLY when it conforms to a specific protocol Swift extension of a class ONLY when it conforms to a specific protocol ios ios

Swift extension of a class ONLY when it conforms to a specific protocol


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  }}


Well, thus far I've found no truly satisfactory way of doing it, but I decided to post what I ended up doing for this particular problem.In a nutshell, the solution goes like this (using the original example code):

protocol MyProtocol{    func protocolFunction() {        //do cool stuff...    }}extension UIViewController //------->simple extension on UIViewController directly{    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)        //------->only run when self conforms to MyProtocol        if let protocolConformingSelf = self as? MyProtocol {             //invoke APIs from              protocolConformingSelf.protocolFunction() // MyProtocol APIs            let viewLoaded = protocolConformingSelf.isViewLoaded // UIViewController APIs        }    }}

Drawbacks:

  • Not "the Swift way" of doing things
  • The swizzling method will be invoked and take effect on ALL UIViewControllers, even though we validate for only those that conform to the MyProtocol protocol to run the sensitive lines of code.

I very much hope it helps anyone else out there facing a similar situation =)