-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Background and Motivation
[This is pretty much a copy of #47601, with an additional aggravating scenario we've run into]
API Proposal
Original specs
- https://github.com/dotnet/designs/blob/main/accepted/2020/platform-checks/platform-checks.md#attributes
- https://github.com/dotnet/designs/blob/main/accepted/2020/platform-exclusion/platform-exclusion.md
This was removed in 5.0 RC: dotnet/docs#20635
ObsoletedInOSPlatformAttribute
was removed, as this annotation is not needed at this time
With the addition of mobile platforms we think the need/time has come :-)
API Usage
Apple commonly obsoletes API and provide better alternatives for them. The headers (both C and Objective-C) includes macros that help developers (and the Xcode IDE) select the best API for the OS version being targeted.
The legacy Xamarin SDKs (iOS/Mac) annotate the API with the similar attributes. They are:
[Introduced]
: specifies in which OS version an API was introduced. This maps perfectly to[SupportedOSPlatform ("ios10.0")]
[Obsoleted]
: Apple will often make API obsolete, and sometimes tell the user which API they're to use instead. This might map to[UnsupportedOSPlatform ("ios15.0")]
, but there's no way to specify a custom message.[Deprecated]
: Some time after an API becomes obsolete, they might become deprecated (which generally means they will be rejected if submitted to one of the Apple App Stores). In this case Apple might also give a message telling the user the better API to use. This might map to[UnsupportedOSPlatform ("ios15.0")]
, but there's no way to map a custom message.[Unavailable]
: specifies an API which is not available anymore (and which we can't remove because it would be a breaking change). This maps perfectly to[UnsupportedOSPlatform ("ios")]
The problematic attributes are [Obsoleted]
and [Deprecated]
, because the [UnsupportedOSPlatform]
attribute doesn't let us give the user a custom message (such as telling them what to do instead).
We've opted for using the [Obsolete]
attribute instead (as was suggested in #47601): [Obsolete ("Starting with iOS 15.0, use XYZ instead")]
.
The problem is the following scenario:
- Developer needs to keep their app working an older iOS version, say iOS 14.
- Apple obsoleted some API in iOS 15, providing an alternative.
The only way to make the build warning-free, is by doing something like this:
#pragma warning disable 618
CalliOS14API ();
#pragma warning restore 618
adding a version check won't change anything:
if (checkForiOS15) {
CalliOS15API ();
} else {
#pragma warning disable 618
CalliOS14API ();
#pragma warning restore 618
}
I believe that adding back the [ObsoletedInOSPlatform]
(which had a Message
property) would allow us to improve this, so that app developers won't get warning about deprecated code that will never run on platforms where the API is deprecated due to version checks.
Ref: dotnet/macios#10170
For reference, we got this design from how Apple/clang declares it: https://clang.llvm.org/docs/AttributeReference.html#availability
Attribute | Explanation |
---|---|
introduced=version | The first version in which this declaration was introduced. |
deprecated=version | The first version in which this declaration was deprecated, meaning that users should migrate away from this API. |
obsoleted=version | The first version in which this declaration was obsoleted, meaning that it was removed completely and can no longer be used. |
unavailable | This declaration is never available on this platform. |
Alternative Designs
Alternatively it might be possible to add a Message
property to the [UnsupportedOSPlatform]
attribute.
Risks
The lack of a solution means that users will have a hard time making their build warning-free.