Swift 3 protocol extension using selector error
<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>