iosswiftconditional-compilationavailability

How to subclass a renamed class? / 'MKPinAnnotationView' was deprecated in iOS 15.0: renamed to 'MKMarkerAnnotationView‘


MKPinAnnotationView was renamed in iOS 15 to MKMarkerAnnotationView.
Up to iOS 14, I subclassed MKPinAnnotationView as

class MyAnnotationView: MKPinAnnotationView {
// …
}  

The problem:
If my app is compiled to iOS 14, I want to declare MyAnnotationView as above.
However if it is compiled to iOS 15, I have to use

class MyAnnotationView: MKMarkerAnnotationView {
// …
}  

How can this be achieved?

On the instruction level, I could use something like

if #available(iOS 15, *) {
// iOS 15
} else {
// iOS 14
}  

But on the class level, apparently only something like

@available(iOS 15, *)
class MyAnnotationView: MKMarkerAnnotationView {   

seems to be available that lets me compile a class if iOS 15 is available, but apparently I cannot avoid compilation of class MyAnnotationView: MKPinAnnotationView { if iOS 15 is available.

So how is this handled in Swift?


Solution

  • As noted by @Paulw11 in other answer, MKMarkerAnnotationView has been available since iOS 11. So there's no need to be on iOS 15 to use it.


    This part is still relevant to other cases like @dfd mentioned for image picker on iOS 14 and earlier versions.


    Not as pretty as it should be, it's worth a shot anyway.

    import MapKit
    
    #if canImport(CoreLocationUI) // Hack for iOS 15?
    public typealias BaseAnnotationView = MKMarkerAnnotationView
    #else
    public typealias BaseAnnotationView = MKPinAnnotationView
    #endif
    
    class MyAnnotationView: BaseAnnotationView {
        
    }