iOS版BLEアプリの作り方【第4回:アプリの設計】
こんにちは。連載企画「iOS版BLEアプリをゼロから作ってみました(企画〜開発〜審査まで)」を担当させていただきました株式会社ERiの澤村です。
企画の趣旨や概要説明はこちらの記事をご覧ください。
第4回目はアプリの設計についてご説明していきたいと思います。
LINBLE Keyboardの設計ポイント①
仕様書が出来上がったら、次は設計フェーズに入ります。今回は特にBluetoothを扱う上で考慮した設計ポイントについて取り上げます。
iOSでBLE通信を行いたい場合は以下のような手順を取ることが多いと思います。
- アドバタイズのスキャン
- スキャン結果から接続先を選ぶ
- 接続を仕掛ける
- 接続が確立したら、サービスやキャラクタリスティックの探索を行う
LINBLE Keyboardの設計ポイントとしては、上記4工程の処理の役割を収容アプリとキーボードアプリに分けたことです。収容アプリでは上記2まで、つまり「デバイスの選択」をさせることに特化させ、上記3以降の処理はすべてキーボードアプリで行うこととしました。
別プロセス間でデータ共有を行うために「App Groups」を使う
処理を分けるということは、収容アプリで選択したデバイス(=ターゲットペリフェラル)をキーボードアプリ側で知る仕組みが必要です。
iOSでは、CBCentralManagerクラスのretrievePeripherals(withIdentifiers:)というメソッドを使うことで、UUIDからペリフェラルを復元することができます。LINBLE Keyboardはこのメソッドを使用するために、選択したペリフェラルのUUIDを収容アプリとキーボードアプリ間で共有しています。
収容アプリとキーボードアプリの別プロセス間でデータ共有を行うためには、App Groupsという機能を使います。
App Groupsとは、同一デベロッパーが開発したアプリをグルーピングすることで、shared containerというローカルストレージ領域を使ってデータを共有できるようにする機能です。
このApp Groupsに、UserDefaultsを使って値の保存を行います。
UserDefaultsは「keyとvalueのペアデータをアプリ内で永続的に保存できる仕組み」で、UserDefaultsでUUIDを共有することで、ターゲットペリフェラルの共有を行っています。
LINBLE Keyboardの設計ポイント②
LINBLE Keyboardの仕様では、「キーボードで接続後、バックグラウンドでも接続を維持すること」としていますが、iOSの仕様を調べたところ、Custom KeyboardのUIInputViewControllerインスタンスは「表示になったら生成/非表示になったら破棄」されてしまうため、UIInputViewControllerインスタンスのプロパティとしてCore Bluetooth関連のオブジェクトを持たせてしまうと、キーボードが非表示になった際にこれらのオブジェクトも破棄されてしまい、接続が維持できなくなってしまうことがわかりました。
そこでバックグラウンドでも接続を維持できるように、このオブジェクトはグローバルにシングルトンパターンで生成しておき、UIInputViewControllerインスタンスから参照を取得するようにします。そうすることで、プロセス単位で一つのCore Bluetooth関連のオブジェクトとすることができ、Custom Keyboardは非表示になってもプロセスは生きているので、接続の維持が可能となります。
なお、Custom Keyboardのプロセスについては、次回の「アプリの開発」で詳細を記載しています。
アプリの設計まとめ
以上、第4回「アプリの設計」について解説しました。
今回はかなり専門的な内容となりましたが、Bluetooth周りの仕様に合わせて設計が変わる場合もあるため、先にしっかり仕様を決めておくことの重要性がご理解いただけたと思います。
次回、第5回目は「アプリの開発」についてお届けします。