Swift2以降はavailableでバージョンを切り分けよう

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

availableはSwift2.0で追加され、プラットフォーム(OS)やSDKのバージョンによってコードを切り分けることが出来ます。
標準APIにも使用されており、例えば UIViewController であれば、以下のような感じで@availableが付いている事を確認出来ます。

@available(iOS 9.0, *)
public func loadViewIfNeeded() // Loads the view controller's view if it has not already been set.
@available(iOS 9.0, *)
public var viewIfLoaded: UIView? { get } // Returns the view controller's view if loaded, nil if not.

public func viewDidLoad() // Called after the view has been loaded. For view controllers created in code, this is after -loadView. For view controllers unarchived from a nib, this is after the view is set.
@available(iOS 3.0, *)
public func isViewLoaded() -> Bool

指定の仕方

コード内で判定する

// iOS 9以降の時実行
if #available(引数) { ... }

Attributeで指定する

@available(引数)

引数内で=と書いている部分は、Swift3.0:置き換わる予定なのでご注意下さい。

引数内の記載について

対応するプラットホームやOSを制御します。 最初の引数はプラットフォーム名になります。

プラットフォーム名

指定出来るプラットフォーム名は下記の通りです。*を指定すると、全プラットフォームが対象となります。

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

利用不可 : unavailable

unavailableをつけると指定したプラットフォームが使えないようになります。

// iOSでは利用出来ない
@available(iOS, unavailable)
func hoge() { ... }

導入 : introduced=version number

指定されたVersionNumberが最初に導入されたことを示しています。

// iOS8.0で導入された
@available(iOS, introduced=8.0)
func hoge() { ... }
``` swift
また、<strong>introduced</strong>は
`
@available(PlatformName VersionNumber, *)
`
という形式で省略して書けます。<br>
↑を書き直すと下記のようになります。
``` swift
// iOS8.0で導入された
@available(iOS 8.0, *)
func hoge() { ... }

非推奨 : deprecated=version number

指定されたVersionNumberが以降で非推奨になったことを示しています。

// iOS8.0から非推奨
@available(iOS, deprecated=8.0)
func hoge() { ... }

※ deprecatedが付いているものは、(非推奨なので使えることは使えますが、)今後のバージョンで消える可能性が高いので避けた方が賢明です。

廃止 : obsoleted=version number

指定されたVersionNumberが以降で廃止になったことを示しています。 廃止になるとそのバージョンから使用不可となります。

// iOS8.0から廃止
@available(iOS, obsoleted=8.0)
func hoge() { ... }

メッセージ : message=""

非推奨または廃止の警告やエラーメッセージを設定できます。

// エラーメッセージのカスタマイズ
@available(iOS, obsoleted=8.0, message="Implement piyo: instead")
func hoge() { ... }

名称変更 : renamed="新しい名前"

廃止をして別の名前した時などに、新しい名前がコンパイラによって表示されます。

@available(iOS, obsoleted=8.0, renamed="Piyo")
class Hoge { ... }

@availability(iOS, introduced=8.0)
class Piyo { ... }

クラスに対して制御

@available(iOS 9.0, *)
public class UIStackView : UIView { ... }

特定のメソッドに対して制御

public protocol UIContentContainer : NSObjectProtocol {
... 中略 ...
    @available(iOS, introduced=2.0, deprecated=8.0, message="Implement viewWillTransitionToSize:withTransitionCoordinator: instead")
    public func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval)

introduced, deprecated, obsoleted, messageは組み合わせて使えます。

// iOS5.0から導入、7.0で非推奨、9.0で廃止
@available(iOS, introduced=5.0, deprecated=7.0, obsoleted=9.0, message="oops! remove for method")
func hoge() { ... }

複数のプラットフォーム

@available(iOS 8.0, OSX 10.10, *)
func hoge() { ... }

参考

The Swift Programming Language (Swift 2.2)