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
:
But also for implementations of tableViewSelectionDidChange
:
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?
For xcode 8.1 >= and swift 3,
add @nonobjc at the beginning of method to silence this warning.
Another cause of this warning when
NSError
is being bridged to Swift:Given this Objective-C delegate method:
That automatically generates this Swift method:
The warning was shown.
In my case the reason was that my class had it's own
Error
type so the signature was resolving toMyClass.Error
rather thanSwift.Error
. The solution was to fully type the Error parameter by changing it toSwift.Error
: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
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.
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:
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?