XCode 8 Warning “Instance method nearly matches optional requirement”

I converted my (macOS) project to Swift 3 in XCode 8 and I get the following warnings with several delegate methods I implement in swift classes:

Instance method 'someMethod' nearly matches optional requirement of protocol 'protocolName'

I get this for several NSApplicationDelegate methods like applicationDidFinishLaunching and applicationDidBecomeActive:

  • CFRelease crash in iOS10
  • Xcode 8 - Provisioning Profile vs. Provisioning Profile (Deprecated)
  • How do I create a Delete-Line Keyboard shortcut in Xcode 8? The Xcode 3 solutions do not work anymore
  • How do you make a shake animation for a button using Swift 3
  • Xcode 9 Bug: Cannot find cdtool
  • Can I delete data from iOS DeviceSupport?
  • enter image description here

    But also for implementations of tableViewSelectionDidChange:
    enter image description here

    enter image description here

    I used code completion to insert the method signatures and also tried copying them from the SDK-headers to rule out typos. The warnings just don’t disappear and the methods are never called.

    What am I missing here?

    8 Solutions Collect From Internet About “XCode 8 Warning “Instance method nearly matches optional requirement””

    We contacted Apple Developer Technical Support (DTS) with this issue.
    They replied that this is a bug in XCode 8.

    We submitted a bug report and hope for a quick update. (Apple Bug Report ID: 28315920).

    If you experience a similar issue, please also file a bug report (referring to ours) so the Apple engineers see its not a single case.


    Update for XCode ≥ 8.1

    The problem seems fixed now, at least for the delegate methods we are using in our project.

    After hours of searching I found this – Swift 3 ObjC Optional Protocol Method Not Called in Subclass

    You can workaround the bug by prefixing the objective-c declaration on the function

    @objc(tableViewSettingsDidChange:notification:)
    func tableViewSettingsDidChange(_ notification:Notification)
    

    For the record, I had the same problem when implementing WKWebView’s didFailProvisionalNavigation delegate method. The solution was to add the @objc declaration and change the type of the last parameter from Error to NSError:

    @objc(webView:didFailProvisionalNavigation:withError:)
    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: NSError) {
        // handle error
    }
    

    Another cause of this warning when NSError is being bridged to Swift:

    Given this Objective-C delegate method:

    - (void)myService:(id<MYService>)myService didFailForSomeReason:(NSError *)error;
    

    That automatically generates this Swift method:

    public func myService(_ myService: MYService!, didFailForSomeReason error: Error!)
    

    The warning was shown.

    In my case the reason was that my class had it’s own Error type so the signature was resolving to MyClass.Error rather than Swift.Error. The solution was to fully type the Error parameter by changing it to Swift.Error:

    public func myService(_ myService: MYService!, didFailForSomeReason error: Swift.Error!)
    

    Here’s what fixed it for me.

    I was getting the same warning in some code that I was sure that I typed into the editor initially and allowed it to autocomplete. I subsequently went back and re-visted the warning and tried to just type the same function over again right after my existing function. When I entered the function name over again, my function signature changed and the parms matched up exactly with what Xcode expected and the warning was suppressed.

    So if you want to do a quick sanity check, do yourself a favor and try typing in the function one more time and see if the parm types change. That might be all you need.

    Just to add clarification to this rather over complicated workaround: can anyone see why the below is not firing/working when the action is being taken?

    extension AppDelegate: UNUserNotificationCenterDelegate {
        @objc(userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:)
        func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
            print("RESPONSE FROM NOTIFICATION!")
    
            switch response.actionIdentifier {
            case "reply":
                print("Reply action received!")
            case "ignore":
                print("Ignore action received!")
            default: print("Error - Unknown action received!")
                break
            }
        }
    }
    

    For xcode 8.1 >= and swift 3,

    add @nonobjc at the beginning of method to silence this warning.

    I found this warning is mainly due to when conform to protocol of UITableViewDelegate instead of UITableViewDataSource

    Please double check if you are missing UITableViewDataSource