• Home / IOS / How to use the #available attribute in Swift

How to use the #available attribute in Swift

  • October 29, 2020

Marking pieces of code as available per platform or version is required in the ever changing landscape of app development. When a new Swift version or platform version arrives, we’d like to adopt to it as soon as possible. Without throwing away support for older versions we can make use of the available attribute in Swift.

This post won’t help you decide for a strategy to decide which minimum iOS version you should support but it will be a useful reference for those times you need to make use of newer APIs.

Checking for an OS version to execute code

A basic example comes down to checking for a specific OS version to execute a piece of code. For example, if you’d like to execute a piece of code only when it’s iOS 14 and up, you would use the available attribute as follows:

if #available(iOS 14, *) {
    print("This code only runs on iOS 14 and up")
} else {
    print("This code only runs on iOS 13 and lower")

You can use the available attribute inside a guard statement as well:

guard #available(iOS 14, *) else {
    print("Returning if iOS 13 or lower")

print("This code only runs on iOS 14 and up")

This is great for cases in which you’d like to execute specific code only for a specific iOS version.

The difference between @available and #available

When navigating through Swift APIs you’ll often run into the @available attribute. We’ve just covered the #attribute which is similar but just a bit different. The shortest answer to describe its difference:

  • @available is used to mark the availability for a class or method
  • #available is used to only execute a piece of code for specific platforms and/or versions

Setting the availability for a class or method

We can demonstrate this by marking a class or method as available since iOS 14:

@available(iOS 14, *)
final class NewAppIntroduction {
    // ..

Once you’ll try to create an instance of this class inside a project that supports versions lower than iOS 14 you’ll run into the following error:

As you can see, the compiler will help us to fix this error with a few suggestions. Two of them will move the problem to a different place in your code by marking the calling class as available since iOS 14 too. The #available will help us in this case:

if #available(iOS 14, *) {
    let appIntroduction = NewAppIntroduction()
} else {
    // .. use the old app introduction

We could do exactly the same for methods using the @available attribute:

@available(iOS 14, *)
func launchNewAppIntroduction() {
    let appIntroduction = NewAppIntroduction()

Possible values for the available attribute

In the above examples we’ve only made use of iOS 14 checks. However, there’s much more we can do with the available attribute in Swift.

Obviously, we could replace the number 14 with any OS version that’s available. The platform, in this case iOS, can be replaced too. The list of available attributes as of today is as follows:

  • iOS
  • iOSApplicationExtension
  • macOS
  • macOSApplicationExtension
  • macCatalyst
  • macCatalystApplicationExtension
  • watchOS
  • watchOSApplicationExtension
  • tvOS
  • tvOSApplicationExtension
  • swift

Options include platforms as well as the swift key to mark pieces of code as available since a specific Swift version.

The asterisk indicates availability of the declaration on all of the platform names listed above, unless specified specifically. You could specify multiple platforms at once as well if required:

@available(iOS 14, macOS 11.0, *)
func launchNewAppIntroduction() {
    let appIntroduction = NewAppIntroduction()

Marking a method as renamed

When developing SDKs for colleagues, open-source, or other users you might want to migrate implementors to newer methods of your code. In these cases you can make use of the renamed attribute:

@available(*, unavailable, renamed: "launchOnboarding")
func launchAppIntroduction() {
    // Old implementation

func launchOnboarding() {
    // New implementation

Note that we’re marking a method as unavailable first. The renamed value indicates which method should be used instead.

Negate available statement

An often asked question when working with the available attribute is to negate the statement and write code like:

Only run this if the iOS version is lower than X

As of today, the only way to do this is by inverting the available check as follows:

if #available(iOS 14, *) { } else {
    // Run iOS 13 and lower code.

This is far from great and results in an empty code block but is currently the only possible way. There’s an open discussion on the Swift forums but it seems that it’s not going to result in any changes in the nearby future.