title: Swift 3 protocol extension using selector error
body: <p>I have what I thought to be a very simple protocol extension for my <code>UIViewController</code>s providing the capability to dismiss a keyboard through a tap gesture. Here's my code:</p>
  
  <pre><code>@objc protocol KeyboardDismissing { 
      func on(tap: UITapGestureRecognizer)
  }
  
  extension KeyboardDismissing where Self: UIViewController {
  
      func addDismissalGesture() {
          let tap = UITapGestureRecognizer(target: self, action: #selector(Self.on(tap:)))
          view.addGestureRecognizer(tap)
      }
  
      func on(tap: UITapGestureRecognizer) {
          dismissKeyboard()
      }
  
      func dismissKeyboard() {
          view.endEditing(true)
      }
  }
  </code></pre>
  
  <p>The problem is that the above code throws a compile error on this line:</p>
  
  <pre><code>let tap = UITapGestureRecognizer(target: self, action: #selector(Self.on(tap:)))
  </code></pre>
  
  <p>With the error message:</p>
  
  <blockquote>
    <p>Argument of '#selector' refers to instance method 'on(tap:)' that is not exposed to Objective-C</p>
  </blockquote>
  
  <p>with the suggestion to "fix it" by adding <code>@objc</code> before <code>func on(tap: UITapGestureRecognizer)</code></p>
  
  <p>Ok fine, I add the tag: </p>
  
  <pre><code>@objc func on(tap: UITapGestureRecognizer) {
      dismissKeyboard()
  }
  </code></pre>
  
  <p>But then, it throws a different compile error on this newly added <code>@objc</code> tag with the error message:</p>
  
  <blockquote>
    <p>@objc can only be used with members of classes, @objc protocols, and concrete extensions of classes</p>
  </blockquote>
  
  <p>with the suggestion to "fix it" by <em>removing the exact same tag I was just told to add</em>.</p>
  
  <p>I originally thought adding <code>@objc</code> before my protocol definition would solve any <code>#selector</code> problems but apparently that's not the case, and these cyclical error messages/suggestions aren't helping in the slightest. I've gone down a wild goose chase of adding/removing <code>@objc</code> tags everywhere, marking methods as <code>optional</code>, putting methods in the protocol's definition, etc.</p>
  
  <p>It also doesn't matter what I put in the protocol definition Leaving the extension the same, the following example does not work nor does any combination of the declared methods in the protocol's definition:</p>
  
  <pre><code>@objc protocol KeyboardDismissing { 
      func on(tap: UITapGestureRecognizer)
  }
  </code></pre>
  
  <p>This tricks me into thinking it works by compiling as a stand alone protocol, but the second I try to add it to a view controller:</p>
  
  <pre><code>class ViewController: UIViewController, KeyboardDismissing {}
  </code></pre>
  
  <p>it spits back the original error.</p>
  
  <p>Can someone explain what I'm doing wrong and how I can compile this?</p>
  
  <p><strong>Note:</strong></p>
  
  <p>I've looked at <a href="https://stackoverflow.com/questions/36184912/swift-2-2-selector-in-protocol-extension-compiler-error">this question</a> but it is for Swift 2.2 not Swift 3 nor does the answer compile as soon as you create a view controller class that inherits from the protocol defined in the example.</p>
  
  <p>I've also looked at <a href="https://stackoverflow.com/questions/33022540/swift-make-protocol-extension-a-notification-observer">this question</a> but the answer uses <code>NotificationCenter</code> which is not what I'm after.</p>
  
  <p>If there are any other seemingly duplicate questions, please let me know.</p>