Custom protocol conformance that supports older version, collides with new system conformance

The problem is best described with an example:

Up until recently, NSImage did not conform to NSItemProviderReading so I've written my own implementation:

extension NSImage: NSItemProviderReading {

    public static var readableTypeIdentifiersForItemProvider: [String] {
        return ["public.image"]
    }

    public static func object(withItemProviderData data: Data, typeIdentifier: String) throws -> Self {
        return NSImage(data: data)! as! Self
    }
}

However, starting with macOS 13.0, NSImage now conforms to the protocol. This has raised a problem: a collision between my old custom implementation and the new system implementation. I still need to keep my own implementation in code, in order to keep things working when the app runs on macOS < 13.0. The problem is I am getting the following compilation errors:

Getter for 'readableTypeIdentifiersForItemProvider' with Objective-C selector 'readableTypeIdentifiersForItemProvider' conflicts with previous declaration with the same Objective-C selector
Method 'object(withItemProviderData:typeIdentifier:)' with Objective-C selector 'objectWithItemProviderData:typeIdentifier:error:' conflicts with previous declaration with the same Objective-C selector

I tried appending @available (macOS, introduced: 10.15, obsoleted: 13.0) to my code, to no effect.

The only workaround I found so far, is subclassing NSImage and write my implementation as an override. Then I use my own class, instead of NSImage.

Is this a limitation? Or am I missing something?

2 Likes

Maybe you could define an “adapter” type instead of subclassing NSImage. The implementation of this adapter can then change depending on the OS version.

2 Likes