The availability attribute

Using the latest SDK gives us access to all of the latest features for the platform that we are developing for; however, there are times when we want to also target older platforms. Swift allows us to use the availability attribute to safely wrap code to run only when the correct version of the operating system is available. The availability was first introduced in Swift 2.

The availability blocks essentially lets us say, "If we are running the specified version of the operating system or higher, run this code. Otherwise, run some other code." There are two ways in which we can use the availability attribute. The first way allows us to execute a specific block of code and can be used with an if or guard statement. The second way allows us to mark a method or type as available only on certain platforms.

The availability attribute accepts up to five comma-separated arguments that allow us to define the minimum version of the operating system or application extension needed to execute our code. These arguments are:

After the argument, we specify the minimum version that is required. We only need to include the arguments that are compatible with our code. As an example, if we are writing an iOS application, we only need to include the iOS argument in the available attribute. We end the argument list with an * (asterisk). Let's look at how we would execute a specific block of code only if we meet the minimum requirements:

if #available(iOS 9.0, OSX 10.10, watchOS 2, *) {
     // Available for iOS 9, OSX 10.10, watchOS 2 or above
    print("Minimum requirements met")
} else {
    //  Block on anything below the above minimum requirements
    print("Minimum requirements not met")
}

In this example, the if #available(iOS 9.0, OSX 10.10, watchOS 2, *) line of code prevents the block of code form executing when the application is run on a system that does not meet the specified minimum operating system version. In this example, we also use the else statement to execute a separate block of code if the operating system did not meet the minimum requirements.

We can also restrict access to a function or a type. In the previous code, the available attribute was prefixed with the # (pound) character. To restrict access to a function or type, we prefix the available attribute with an @ (at) character. The following example shows how we would restrict access to a type and function:

@available(iOS 9.0, *)
func testAvailability() {
    // Function only available for iOS 9 or above
}

@available(iOS 9.0, *)
struct TestStruct {
  // Type only available for iOS 9 or above
}

In the previous example, we specify that the testAvailability() function and the testStruct() type can only be accessed if the code is run on a device that has iOS version 9 or above. In order to use the @available attribute to block access to a function or type, we must wrap the code that calls that function or type with the #available attribute. The following example shows how we would call the testAvailability() function:

if #available(iOS 9.0, *) {
    testAvailability()
} else {
     // Fallback on earlier versions
}

In this example, the testAvailability() function is only called if the application is running on a device that has iOS version 9 or above.