ゴール
Swiftにおけるストアドプロパティで @available を指定する
前提条件
- iOS(macOS, watchOSでも同様)アプリにおいて、deployment targetをiOS 13にしつつ、iOS 14から利用可能なAPIをiOS 14系のユーザのみ使用したい
- @available を使用することでユーザのデバイスにおけるOS versionによってアプリの処理を変更することができる
@availableのサンプル
// 特定のOS versionのみ利用可能なclassの指定
@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, *)
class MyClass {
// class definition
}
// iOS 13以降のversionで利用可能なstructの指定
@available(iOS 13.0, *)
struct MyStruct {
// struct definition
}
// メソッドにおけるversion指定
@available(iOS 14, *)
func limitOSVersion() {
}
// 特定のOS versionにおける条件分岐
if #available(iOS 13, *) {
print("iOS 13以降が実行される")
} else {
print("iOS 13未満が実行される")
}
guard #available(iOS 13, *) else {
print("iOS 13未満が実行される")
return
}
print("iOS 13以降が実行される")
詳細は下記を参照
https://docs.swift.org/swift-book/ReferenceManual/Attributes.html
問題点
プロパティにおいても下記のように@availableを設定すると、下記コンパイルエラーが発生する
Stored properties cannot be marked potentially unavailable with '@available'
@available(iOS 14.0, *)
struct Fuga {
let aaa: String
}
struct Hoge {
@available(iOS 14, *)
let fuga: Fuga // Stored properties cannot be marked potentially unavailable with '@available'
}
解決方法
- lazy varで指定する
- version要求のないprotocolで宣言して、動的にversion要求のある対象を設定する
1. lazy varで指定する
struct Hoge {
@available(iOS 14.0, *)
lazy var fuga = Fuga(aaa: "test")
}
2. version要求のないprotocolで宣言して、動的にversion要求のある対象を設定する
protocol NonRequiredVersion {}
@available(iOS 14.0, *)
struct Fuga: NonRequiredVersion {
let aaa: String
}
struct Hoge {
let fuga: NonRequiredVersion?
init() {
if #available(iOS 13, *) {
fuga = Fuga(aaa: "test")
} else {}
}
}
参考になれば幸いです