9

I wish to achieve something like that:

@unavailable(iOS 11.0, *) func oldWay() { ... } @available(iOS 11.0, *) func newWay() { ... } 

I've tried things like @available(iOS 11.0, unavailable, *) but it does not compile.

My problem is that I'm conforming to an Objective-C protocol with optional methods. Some of them are only available since iOS 11, my app is available since iOS 10 and I don't want to have both methods implemented for a given platform.

For instance if I do this:

func oldWay() { ... } @available(iOS 11.0, *) func newWay() { ... } 

Both methods are implemented on all platforms since iOS 11... That's not what I'm looking for.

So if anyone has an idea...

1
  • Would you be better off inheriting from the protocol with your own protocol version written in ObjC? If you did that, seems like you could go macro-crazy, and probably get it to do what you want. Commented Apr 10, 2020 at 14:55

1 Answer 1

5

You can use the deprecated: argument (and potentially message: as well), because that seems to be what's happening here:

@available(iOS, deprecated: 11.0, message: "Please use 'newWay'") func oldWay() { } @available(iOS 11.0, *) func newWay() { } 

This will produce a warning if you try to use the old way. If you want an error instead, replace deprecated with obsoleted.

Sign up to request clarification or add additional context in comments.

6 Comments

I don't want deprecation, but unavailablilty. A deprecated method is still compiled and implemented. Moreover the Objective-C code when testing if a method is implemented has no information on deprecation.
@Zaphod Looking at the generated headers, methods marked with obsoleted look like this - (void)foo SWIFT_AVAILABILITY(ios,obsoleted=11.0);. I don't know much Objective-C, but can't you check for that? To me, this sounds like you need to rewrite the code that "tests if a method is implemented", rather than your Swift code.
obsoleted compiles for me, thanks @Sweeper, learned something here. I suggested inheriting the protocol in ObjC above, might be easier.
The Obj-C protocol is not mine, unfortunately. I think the outcome is still different, because when it's not available, you simply does not have the implementation, do you? If you write @available(iOS, unavailable) you won't have it at all in the headers. Besides, I just want the Objective-C method respondsToSelector to return false for this method.
@Zaphod It will still be in the headers even if you write @available(iOS, unavailable). It will appear as - (void)foo SWIFT_UNAVAILABLE;. If you just want respondsToSelector to return false, I guess you could always manually override it... Not a "clean" solution per se, but it should work...
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.