Xcode 8 Warning "Instance method nearly matches optional requirement"

20,137

Solution 1

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.

Solution 2

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)

Solution 3

One reason you might get this error has to do with method access modifiers. For example if you didn't define the function as public. So for methods on the CLLocationManagerDelegate case, changing:

func locationManager(_ manager: CLLocationManager,
                     didChangeAuthorization status: CLAuthorizationStatus)

to:

public func locationManager(_ manager: CLLocationManager,
                            didChangeAuthorization status: CLAuthorizationStatus)

(i.e. make the method public) gets rid of the warning and the method get called as expected. Note that autocomplete doesn't put the public access modifier on the method.

Solution 4

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!)

Solution 5

for me the problem was custom Error class
Basically I had my own class with name Error and compiler was considering delegate method as a local method

I just changed name of my own class name and it worked. So, just confirm that you don't have any class name same in the function

Share:
20,137
codingFriend1
Author by

codingFriend1

📓 Developer of Loqbooq, a Slack and web app for decision logging and ADR. 💬 Maker of the vocabulary learning app Wokabulary for iPhone, iPad and Mac. 🧁 Developer of Macarons, a chat roulette app for Slack. 📝 Contributor to the open source text editor Tincta for Mac. 🛡 Blogging on security for most people on passwort1.de

Updated on October 28, 2020

Comments

  • codingFriend1
    codingFriend1 over 3 years

    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:

    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?