/// Check if APIs from the given operating system versions are available. /// /// Apple adds new APIs with new OS releases, and as a developer, you often /// want to use those to give your users the best behaviour, while still /// supporting older OS versions that don't have those APIs (instead of /// crashing e.g. because of an undefined selector). /// /// This macro allows you to conditionally execute code depending on if the /// current OS version is higher than or equal to the version given in the /// macro. /// /// If no version is specified for a certain OS, the API will be assumed to be /// unavailable there. This default can be changed by adding a trailing `..` /// to the macro invocation. /// /// This is very similar to `@available` in Objective-C and `#available` in /// Swift, see [Apple's documentation][apple-doc]. Another great introduction /// to availability can be found in [here][epir-availability]. /// /// [apple-doc]: https://developer.apple.com/documentation/xcode/running-code-on-a-specific-version#Require-a-minimum-operating-system-version-for-a-feature /// [epir-availability]: https://epir.at/2019/10/30/api-availability-and-target-conditionals/ /// /// /// # Operating systems /// /// The operating system names this macro accepts, the standard environment /// variables that you use to raise the deployment target (the minimum /// supported OS version) and the current default versions are all summarized /// in the table below. /// /// | OS Value | Name | Environment Variable | Default | /// | ---------- | ----------------------- | ---------------------------- | ------- | /// | `ios` | iOS/iPadOS/Mac Catalyst | `IPHONEOS_DEPLOYMENT_TARGET` | 10.0 | /// | `macos` | macOS | `MACOSX_DEPLOYMENT_TARGET` | 10.12 | /// | `tvos` | tvOS | `TVOS_DEPLOYMENT_TARGET` | 10.0 | /// | `visionos` | visionOS | `XROS_DEPLOYMENT_TARGET` | 1.0 | /// | `watchos` | watchOS | `WATCHOS_DEPLOYMENT_TARGET` | 5.0 | /// /// The default version is the same as that of `rustc` itself. /// /// /// # Optimizations /// /// This macro will statically be set to `true` when the deployment target is /// high enough. /// /// If a runtime check is deemed necessary, the version lookup will be cached. /// /// /// # Alternatives /// /// Instead of checking the version at runtime, you could do one of the /// following instead: /// /// 1. Check statically that you're compiling for a version where the API is /// available, e.g. by checking the `*_DEPLOYMENT_TARGET` variables in a /// build script or at `const` time. /// /// 2. Check at runtime that a class, method or symbol is available, using /// e.g. [`AnyClass::get`], [`respondsToSelector`] or [weak linking]. /// /// [`AnyClass::get`]: crate::runtime::AnyClass::get /// [`respondsToSelector`]: crate::runtime::NSObjectProtocol::respondsToSelector /// [weak linking]: https://github.com/rust-lang/rust/issues/29603 /// /// /// # Examples /// /// Use the [`effectiveAppearance`] API that was added in macOS 10.14. /// /// ``` /// # #[cfg(available_in_frameworks)] /// use objc2_app_kit::{NSApplication, NSAppearance, NSAppearanceNameAqua}; /// use objc2::available; /// /// let appearance = if available!(macos = 10.14) { /// // Dark mode and `effectiveAppearance` was added in macOS 10.14. /// # #[cfg(available_in_frameworks)] /// NSApplication::sharedApplication(mtm).effectiveAppearance() /// } else { /// // Fall back to `NSAppearanceNameAqua` on macOS 10.13 and below. /// # #[cfg(available_in_frameworks)] /// NSAppearance::appearanceNamed(NSAppearanceNameAqua).unwrap() /// }; /// ``` /// /// Use an API added in Xcode 16.0 SDKs. /// /// We use `..` here in case Apple adds a new operating system in the future, /// then we probably also want the branch to be taken there. /// /// ``` /// use objc2::available; /// /// if available!(ios = 18.0, macos = 15.0, tvos = 18.0, visionos = 2.0, watchos = 11.0, ..) { /// // Use some recent API here. /// } /// ``` /// /// Set the [`wantsExtendedDynamicRangeContent`] property, which is available /// since iOS 16.0, macOS 10.11 and visionOS 1.0, but is not available on tvOS /// and watchOS. /// /// ``` /// use objc2::available; /// /// if available!(ios = 16.0, macos = 10.11, visionos = 1.0) { /// # #[cfg(available_in_frameworks)] /// layer.setWantsExtendedDynamicRangeContent(true); /// } /// ``` /// /// Work around problems in a specific range of versions (an example of this /// in the real world can be seen in [#662]). /// /// ``` /// use objc2::available; /// /// if available!(macos = 15.0) && !available!(macos = 15.1) { /// // Do something on macOS 15.0 and 15.0.1. /// } else { /// // Do something else on all other versions. /// } /// ``` /// /// [`effectiveAppearance`]: https://developer.apple.com/documentation/appkit/nsapplication/2967171-effectiveappearance?language=objc /// [`wantsExtendedDynamicRangeContent`]: https://developer.apple.com/documentation/quartzcore/cametallayer/1478161-wantsextendeddynamicrangecontent /// [#662]: https://github.com/madsmtm/objc2/issues/662 /// then we probably also want the branch to be taken there.
/// if available!(ios = 18.0, macos = 15.0, tvos = 18.0, visionos = 2.0, watchos = 11.0, ..) {
//// Set the [`wantsExtendedDynamicRangeContent`] property, which is available
macro_rules/// and watchOS.///
( // Returns `false` on unspecified platforms.
$(
$os:ident $(= $major/// # #[cfg(available_in_frameworks)]
),* $(,)?
) => /// ```
$crate:/// in the real world can be seen in [#662])./// use objc2::available;///
/// // Do something else on all other versions. #[allow(clippy::needless_update)] const VERSION: $crate::/// [`wantsExtendedDynamicRangeContent`]: https://developer.apple.com/documentation/quartzcore/cametallayer/1478161-wantsextendeddynamicrangecontent
$(
java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71 // helpful to write it like this for documentation. // // We use optionality for the version here, to allowjava.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
filled.
$os: $($crate)java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 18 // A version this high will never be lower than the deployment // target, and hence will always return `false` from / `is_available`.
. $crate::_macro_helpers:AvailableVersion::
}
Vjava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
)
};
( // Returns `true` on unspecified platforms because of the trailing `..`.
$(
$os:ident $(= $major:literal $(. $minor:literal $(. $patch:literal)?)?)?,
)*
..
) => {
$crate::__macro_helpers::is_available({ #[allow(clippy::needless_update))java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
c $::=$_:java.lang.StringIndexOutOfBoundsException: Range [113, 112) out of bounds for length 114
(
$os: $($crate::__available_version)java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
)java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18 // A version of 0.0.0 will always be lower than the deployment // target, and hence will always return `true` from // `is_available`. //
We thiswhen `. specified.
.. $crate;
};
VERSION
})
};
}
/// Both `tt` and `literal` matches either `$major` as an integer, or /// `$major.$minor` as a float. /// /// As such, we cannot just take `$major:tt . $minor:tt . $patch:tt` and /// convert that to `OSVersion` directly, we must convert it to a string /// first, and then parse that. /// /// We also _have_ to do string parsing, floating point parsing wouldn't be /// enough (because e.g. `10.10` would result in the float `10.1` and parse /// wrongly). /// /// Note that we intentionally `stringify!` before passing to `concat!`, as /// that seems to properly preserve all zeros in the literal. #[doc(hidden)] #[macro_export/// `$major.$minor` as a float.
macro_rules! __/// convert that to `OSVersion` directly, /// first, and then parse that. // Just in case rustc's parsing changes in the future, let's handle this // generically, instead of trying to split each part into separate `tt`.
($($version_part_or_period:tt)*) => {
$crate::__macro_helpers::OSVersion:: // Just in case rustc's parsing changes in
$crate::__macro_helpers// generically, instead of trying to split each part into separate `tt`.
)*)
java.lang.StringIndexOutOfBoundsException: Range [14, 4) out of bounds for length 6
}
Messung V0.5 in Prozent
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.14Bemerkung:
(vorverarbeitet am 2026-08-25)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.