How To Use Availability Checking In Swift

How To Use Availability Checking In Swift

Swift includes a number of features Objective-C developers have wanted for years. Availability checking is one of those features.

In Objective-C, applications check at runtime whether a class or instance of a class implements (responds to) a particular method. Even though this works fine most of the times, it is possible that a public API started its life as a private API in an earlier version of the operating system. And you probably know how Apple feels about developers using private APIs.

Swift offers a much better and more reliable solution, availability checking. Availability checking is built into the Swift programming language. It is the solution developers have wanted all along.

How Does It Work?

In iOS 8, Apple changed the APIs for working with notification settings. If you are working on an application that supports an earlier version of iOS, then you are forced to use the deprecated APIs for registering for remote notifications. Fortunately, Swift makes this easy and safe.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    if #available(iOS 8.0, *) {
        // Create User Notification Settings
        let userNotificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)

        // Register User Notification Settings
        application.registerUserNotificationSettings(userNotificationSettings)

    } else {
        // Register for Remote Notification Type
        application.registerForRemoteNotifications(matching: [.alert, .badge, .sound])
    }

    return true
}

The syntax is clear and concise. You use #available followed by a comma separated list of platform names and versions. The asterisk at the end of the list is required. It is a placeholder for future platforms.

How You Can Use It?

The availability syntax only works if the APIs you are using support it. Fortunately, it is easy to add support to your own libraries for the availability syntax.

In the example below, we use the @available attribute to indicate that the CircularView class is only available on iOS 8 and higher.

import UIKit

@available(iOS 8.0, *)
class CircularView: UIView {

    @available(iOS 8.0, *)
    func someMethod() {
        ...
    }

    @available(iOS 9.0, *)
    func anotherMethod() {
        ...
    }

}

You can use the @available attribute for any symbol, including classes, structures, enumerations, and methods. Nesting is important, though. For example, a method of a class cannot be more available than the class itself. In the above example, the compiler will throw an error if we set the availability of someMethod() to iOS 7.0.

At the time of writing, the availability syntax supports iOS, OS X, tvOS, and watchOS, including extensions for these platforms.

  • iOS
  • iOSApplicationExtension
  • OSX
  • OSXApplicationExtension
  • tvOS
  • tvOSApplicationExtension
  • watchOS
  • watchOSApplicationExtension

What's Next?

If you are familiar with Objective-C, then Swift's availability checking is a welcome addition to Cocoa development. Not only is code easier to read, the compiler warns you if you try to use an API that is not available. Questions? Leave them in the comments below or reach out to me on Twitter.