質問: 現在、swift3/Xcode8で AVFoudationを使用してカメラアプリAとカメラアプリBを作成しています。 2つのカメラアプリの詳細は下記の通りです。 ■カメラアプリA Deployment Target9.0 AVCaptureStillImageOutputを使用。 ■カメラアプリB Deployment Target10 AVCapturePhotoOutputを使用。 今後カメラアプリAとカメラアプリBを混ぜ合わせたカメラアプリCを作成したいと 思っています。 カメラアプリCの詳細は下記の通りです。 ■カメラアプリC Deployment Target9.0 ユーザ様がiOS9ならば、アプリ側ではAVCaptureStillImageOutputを適用。 ユーザ様がiOS10ならば、アプリ側ではAVCapturePhotoOutputを適用。 さっそくDeployment Target9.0でコーディングしていったものの、 下記のようなエラーが表示されました。 ![イメージ説明](https://teratail.storage.googleapis.com/uploads/contributed_images/57f30d40a53e6c9d7ebe9e107de54f5d.png) AVCapturePhotoOutputは、iOS 10以降でのみ利用可能ですという意味だと 思います。 Deployment Target10.0で、AVCapturePhotoOutputを 使用してカメラアプリCを作成すると、 現在iOS9のユーザ様は多分カメラアプリCを使って遊ぶことができないと思います。 また、Deployment Target10.0で、AVCaptureStillImageOutputの使用は 非推奨のため、今後いつAVCaptureStillImageOutputが使えなくなるのか よくわからないため心配です。 質問です。 カメラアプリCを作成する上で、Deployment Target9.0で、 iOS9のユーザ様には、AVCaptureStillImageOutputを適用。 iOS10のユーザ様にはAVCapturePhotoOutputを適用するような コーディングは可能でしょうか。 説明が難しくてすみません。 以上、よろしくおねがいいたします。
回答: Swift2なのでSwift3の場合は適当に修正して下さい。 (その1) iOSのバージョンを調べる ==================== NSProcessInfo.processInfo()を使います。 ``` if (NSProcessInfo.processInfo().isOperatingSystemAtLeastVersion(NSOperatingSystemVersion(majorVersion: 10, minorVersion: 0, patchVersion: 0))) { print("iOS 10.0.0 or later") } ``` 10.0.0以上であればmajorVersionだけ調べればいいので、 ``` if (NSProcessInfo.processInfo().operatingSystemVersion.majorVersion >= 10) { print("iOS 10.0.0 or later") } ``` これでも大丈夫かと思います。 (その2) クラスの存在を調べる ================= バージョンを確認するよりも、クラスが存在するかどうか確認した方が確実かも知れません。 ``` if let _ = NSClassFromString("AVCapturePhotoOutput") { //AVCapturePhotoOutputの処理 } ``` (その3) メンバ変数の対応 =============== 私の方法(その1、その2)はもちろんのこと、fromageblancさんの方法も、関数の外では使えないようなので、photoOutputの定義部分には適用できないですね。 ということで.. (3-1) Anyを使う 使うときにキャストしないといけないことがあると思います。 ``` class Hoge { var photoOutput: Any? func hoge() { if #available(iOS 10, *) { photoOutput = AVCapturePhotoOutput() } } } ``` (3-2) @available()を使う ただし、ストアドプロパティには使えないようなのでタイププロパティにします。 `(クラス名).(プロパティ名)`でアクセスします。 ``` class Hoge { @available(iOS 10.0, *) //10.0以上でのみ定義される static var photoOutput: AVCapturePhotoOutput! func hoge() { if #available(iOS 10, *) { Hoge.photoOutput = AVCapturePhotoOutput() } } } ``` 3-1も3-2も、未検証ですし、やり方としていいのか悪いのかも分かりません。