title: Swift extension of a class ONLY when it conforms to a specific protocol
body: <p>Hi there =) I was just faced with a design problem where I need to (essentially) do the following:</p>
  
  <p>I want to inject a bit of code on <code>viewWillAppear:</code> of <strong>any <code>UIViewController</code> subclass that conforms to a protocol <code>MyProtocol</code></strong>. Explained in code:</p>
  
  <pre><code>protocol MyProtocol
  {
      func protocolFunction() {
          //do cool stuff...
      }
  }
  
  extension UIViewController where Self: MyProtocol //&lt;-----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
  
      }
  }
  </code></pre>
  
  <p>The main issue here is that I need to 2 two things in the <code>UIVIewController</code> extension:</p>
  
  <ol>
  <li>Invoke both <code>MyProtocol</code> and <code>UIViewController</code> API's</li>
  <li>Override <code>UIViewController</code> method <code>initialize()</code> in order to be able to swizzle <code>viewWillAppear:</code></li>
  </ol>
  
  <p>These 2 capabilities seem incompatible (as of Swift 3) because:</p>
  
  <ol>
  <li>We <strong>can't extend classes with conditions</strong> (i.e <code>extension UIViewController where Self: MyProtocol</code>)</li>
  <li>if we instead <strong>extend the protocol</strong>, we CAN add conditions <code>extension MyProtocol where Self: UIViewController</code> but <strong>we CAN'T override methods from a class in a protocol extension</strong>, meaning we can't <code>public override class func initialize()</code> which is needed for swizzling.</li>
  </ol>
  
  <p>So I was wondering if there's somebody out there who can offer a Swifty solution to this problem I'm facing?  =)</p>
  
  <p>Thanks in advance!!</p>