SKYPCEのiPhoneアプリでも利用されているiPhoneのカメラで利用できるVisionKitの紹介です。
SKYPCEではiPhoneアプリを用いて、名刺画像の撮影が可能です。
この機能実現のために利用された、iPhoneの機能は、俗にいうVisionKitと呼ばれる画面で、Apple社より提供されているフレームワークの一つです。
SKYPCEのiPhoneアプリでこのフレームワークの採用となったきっかけは
- 名刺を画面に映すと自動でシャッターを切ってくれる
- 少しくらい傾いていても正面になるように補正してくれる
- 何よりきれいに撮影できる
といった利点が多くあったためです。圧倒的な撮影性能からスマホアプリに取り込むことになりました。
デメリットとしてはVisionKit自体のカスタマイズは公式的には皆無で、自由度はほぼゼロという点があります。
※なお、AndroidアプリではこのVisionKitが使用できないので、VisionKitに近い機能を持つ撮影画面をモバイル開発を主とした社内の別グループが作成しました。
このVisionKit画面は、アプリが回転を許容していれば端末を横向きにしても画面が自動でレイアウト更新してくれるのでとても便利です。
しかし、SKYPCEアプリそのものはiPhone端末の回転に対応させていないため、実装には課題がありました。
通常では、画面クラス[UIViewController]のプロパティをオーバーライドして画面毎に回転の要否を指定するという方法になるかと思います。
override var shouldAutorotate: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
return .all
}
supportedInterfaceOrientationsの戻り値を.allにすると回転し、.portraitにすると縦向きで固定するといった動作になります。
しかし、VisionKitはカスタマイズができないので、画面側で回転制御の指定を変更することができません。
一般的な名刺は横向きが大半なので、よりきれいな画像で名刺を撮影していただくためにこのSKYPCEアプリではVisionKit画面だけは端末の回転に対応させたいと思いました。
UIInterfaceOrientationMaskのグローバル変数を宣言する
var globalOrientation: UIInterfaceOrientationMask = .portrait
大半の画面では回転を許容しない場合、.portraitを指定します。
AppDelegateにsupportedInterfaceOrientationsForを実装する
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return globalOrientation
}
戻り値の変数を変更しなければ、.portraitが返ることになりアプリの表示は固定されます。
VisionKit画面を表示する際にグローバル変数を更新する
let documentCameraViewController = VNDocumentCameraViewController()
documentCameraViewController.delegate = self
present(documentCameraViewController, animated: true)
このようにVisionKit画面を呼び出すときではなく、VisionKit画面に遷移することで呼び出し元画面が非表示となる際に呼び出される viewWillDisappearのタイミングで行います。
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// VisionKit画面に遷移する時だけ以下の更新を行う
globalOrientation = .all
}
presentのタイミングで行ってしまうと、例えばVisionKit画面に遷移する操作の前から端末を横向きにしていた場合、元の画面が一瞬崩れて表示されてしまいます。
VisionKit画面から元の画面に戻ってきた場合は、グローバル変数の値を .portraitに戻せば、元通り回転しない状態に戻ります。
iOSアプリでの回転制御は簡単なように見えてなかなか融通が利かなかったりします。
簡単かと思ってもまずは動かしてみることが大事だと実感しました!