Non - '@ objc' method does not satisfy optional requirements of @objc protocol with conditional extension

I am trying to create a standard MKMapViewDelegate implementation using a conditional extension as follows:

extension MKMapViewDelegate where Self: NSObject { func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { ... } func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { ... } } 

However, when I compile the code, I get a warning

Not the '@ objc' method 'mapView (_: viewFor :)' does not meet the optional protocol requirements @objc 'MKMapViewDelegate'

I expected that matching the NSObject Self would mean that a warning would not occur. In addition to warning, delegate methods are not called, although the delegate instance is a UIViewController and therefore corresponds to NSObject.

I don’t understand how “where” works in extensions?

+7
swift swift-extensions
source share
1 answer

NSObject will no longer output @objc on Swift 4 due to the adoption of Doug Gregor's Proposal: SE-0160 .

I admit that I did not set the time to understand the cause of your mistake. I simply posted this answer in the hope that someone else would read your question, would have the following advice.

This is bad practice or “code smell” to provide a default protocol implementation for your entire module. I would recommend an alternative approach in which you create a custom type like MapViewDelegate , with some default behavior that can be used in conjunction with types that explicitly conform to this protocol .

For example:

 import MapKit protocol MapViewDelegate: MKMapViewDelegate {} extension MapViewDelegate where Self: NSObject { func annotationView(for annotation: MKAnnotation, in mapView: MKMapView) -> MKAnnotationView? { … } func renderer(for overlay: MKOverlay, in mapView: MKMapView) -> MKOverlayRenderer { … } } final class MyMapDelegate: NSObject, MapViewDelegate { func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { return annotationView(for: annotation, in: mapView) } func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { return renderer(for: overlay, in: mapView) } } 
0
source share

All Articles