available()
The available()
function provides the same functionality as the if #available
language syntax in Swift, but makes it accessible to all languages.
Syntax:
method available(params platforms: array of String): Boolean;
bool available(params String[] platforms);
func available(_ platforms: String...) -> Bool
bool available(String... platforms);
Function available(platforms As String[]);
available()
can be used to protect code that will only work on specific newer versions of the platform, by specifying the minimum platform version required. Like if #available
in Swift, it serves three purposes at once:
- It returns a boolean that can be used to check the platform version at runtime.
- In combination with an
if
statement, it will tell the compiler to automatically omit any Deployment Target warnings in the code that is protected by theif available
clause (on supported platforms). - Also inside an
if
statement, it tells the compiler to ignore the code when building for a lower Target SDK (again, on supported platforms).
For the second part to have affect, the call to assigned()
must be the only condition in the if
statement, or the first of multiple conditions combined with the logical and
(Oxygene) or &&
(C# and Swift) operator.
available()
expects one or more strings as parameter. Each string must be a platform name, optionally followed by a space and version number. The version number can consist of one, two or three parts (i.e. "iOS 16", "iOS 16.1" or "iOS 15.7.1"). Platform names are not case sensitive.
Compile-time check to exclude unavailable code portions for compilation is available on the nativer Cocoa platforms (checking against the active macOS, iOS, tvOS or watchOS SDK version) as well as on .NET and Java (checking against the used Target Framework Version or Java Development Kit Version, respectively, not the Operating System version!).
Supression of Deployment Target-related warnings is available on the nativer Cocoa platforms only.
The following platform names are supported:
Name | Version | Comments |
---|---|---|
Windows | Windows OS version | Any app running on Windows: .NET, Java or native Windows |
Linux | Linux kernel version | Any app running on Linux: .NET/Mono, Java or native Linux |
macOS, Mac | macOS Version | Any app running on Mac: native Cocoa, .NET/Mono or Java |
iOS | iOS Version | Any native Cocoa app running on iOS |
tvOS | tvOS Version | Any native Cocoa app running on tvOS |
watchOS | watchOS Version | Any native Cocoa app running on watchOS |
Mac Catalyst | iOS Version | Any native Cocoa app running on macOS via Mac Catalyst |
Android | Android OS version | Any Java or Android NDK-based app |
Android NDK | Android OS version | Any Android NDK-based app |
Android SDK | Android OS version | Any Java app |
.NET | NET/.NET Core Runtime version | Any .NET app running on .NET, .NET Core or Mono |
Java | Java runtime version | Any Java app running on the JVM |
If the current platform is not represented in the list, available()
will return false
for this platform, unless the list of platforms is terminated with a wildcard ("*"
) string. For example, the code below checks for a specific iOS and macOS version. When compiled for run on watchOS or tvOS, the code inside the if
statement will run regardless of version, because these two platforms are being covered by *
.
For example,
available("macOS 13", ".NET 4.5")
will run on *macOS 13 and later or when running on .NET 4.5 and later (on any platform).available("macOS 13", ".NET 4.5", "*")
will run on *macOS 13 and later or when running on .NET 4.5 and later (on any platform) and run without restrictions if not either on macOS or .NET (e.g. if running on Java on Windows).
Please refer to the Deployment Targets topic for further discussion on this.
Example
if available("iOS 12.0", "macOS 10.14", "*") then begin
// code that requires the new OS.
end;
if (available("iOS 12.0", "macOS 10.14", "*"))
{
// code that requires the new OS.
}
if available("iOS 12.0", "macOS 10.14", "*") {
// code that requires the new OS.
}
if (available("iOS 12.0", "macOS 10.14", "*")) {
// code that requires the new OS.
}
- The code inside the
if
statement will only be executed if the platform requirements (in this case, iOS 12 or later, or macOS 10.14 or later) are met. - Any deployment target warnings the code inside the
if
statement would normally emit will be suppressed, because the compiler "knows" that the code will not run on the lower deployment targets. - When building the project for a Target SDK lower than iOS 12 or macOS 10.14, the code will actually be treated as if it was #ifdef'ed out.
- When building for any platform othere than iOS or macOS, the code will compiled and run (because the "*" wildcard was provided).
As such, available()
makes it easy to create apps build for a new Target SDK that can regress gracefully on older systems and to also (optionally) keep your project able to build against the older Target SDK.
This is particularly helpful during the beta phase of a new Apple OS, when Apple does not allow shipping apps built with the new SDK yet: you can start adopting new APIs in your code, and test them locally and in TestFlight beta builds when you build with the new SDK, and you can still build your app against the old SDK, to submit interim builds to the store.
Swift
Note that in Swift,
if available("iOS 9.0", "OS X 10.11") {
is equivalent to the Swift-specific #available
syntax. Both versions will work identical.
if #available(iOS 9.0, OS X 10.11) {
Under the hood, available()
calls the __ElementsPlatformAndVersionAtLeast()
helper function defined in the Toffee Base Library, Island RTL, and Elements RTL. Projects that do not reference one of these three libraries cannot use available()
.
See Also
- Deployment Targets on Cocoa
defined()
System Functionexists()
System Functionstatic()
System Function