Core Bluetooth / Bluetooth Low Energy で iOS アプリと連携する新規ハードウェアを開発したことのある人にとってはあるあるな話だと思うのですが、開発途中でペリフェラル側(外部デバイス)で GATT の内容を変更すると、iPhone の Settings から Bluetooth を Off/On しないと変更が反映されない、というのがあります。
このことを知らないと、
- キャラクタリスティックの `value` が取れない
- -> BLE の接続状態を疑う
- -> Central / Peripheral 間での UUID の食い違いを疑う
- etc...
と、無駄なデバッグ作業をしてしまいかねません。
下記スライドでも最後の方のページで「ハマりどころ」として紹介されています。
しかし例えばデバイス側の GATT に Characteristic をひとつ追加したとして、リリース済みサービスの場合、エンドユーザーに Off/On してもらうっておかしくない?と思い、せっかくなので現在絶賛参加中の WWDC 2014 の "Accessories and I/O Technologies Lab" で質問してみました。
Appleの公式回答
質問してみると、「あーー Cache の件ね!」とすぐに質問の意図を理解してもらえたので、やはりあるあるケースなようです。
で、まずは Bluetooth.org の Core Specifications を見よう、と。
Core Specifications は下記ページより ダウンロードできます。
目次をみると1351ページ以上(!)もあるPDFなのですが、その「7.1 SERVICE CHANGED」という項目があるので、そこを読めと。
どうやら、サービスに変更があった場合に使うキャラクタリスティック "Service Changed" が標準で定義されているのでそれを使えばいいよ、ということらしいです。
なるほど、となったところで「そういうことだから、じゃ!」となりそうだったので、ちょっと待って、iOS側はそのキャラクタリスティックに対してどうしたらいいの、 勝手にキャッシュクリアしてくれるの?それともアプリ内で明示的に何らかの処理をする必要があるの? ということを聞いたところ、
デバイス側で上述したキャラクタリスティックをGATTに追加しておいて必要に応じてサービス変更を通知すると、
CBPeripheralDelegate の `peripheral:didModifyServices:` が呼ばれる
ので、そこで再度 `discoverServices:` すればOKとのこと。
余談:ラボ初体験記
WWDCは今回が初参加で、「セッションは動画がすぐに公開されるので行かなくてよい、WWDCはラボで質問しまくってこそ価値がある!」と聞いてたので、「ラボで何か聞かないと・・・でも不安だ・・・」(英語コミュニケーション的な意味で)とプレッシャーを感じていました。
3コマ目は"Mastering Modern Media Playback"に来たけど、途中で切り上げて"Accessories and I/O Technologies Lab"に行くかも。でもラボ怖い。
— Tsutsumi Shuichi (@shu223) 2014, 6月 3
でもBLEについて聞けそうなラボはそんなにないので今いくしかない!と部屋に入ったものの、
ラボ初挑戦してみたけどAccessoryをAccelerateと聞き間違えられた(たまたま同じ部屋)あたりで少し及び腰になり、案内の人が言ってることが聞き取れず、順番待ちのルールがよくわからないあたりで心が折れてランチに逃げた。 #WWDC
— Tsutsumi Shuichi (@shu223) 2014, 6月 3
といったんは逃げ帰りました。
ランチ後、「今年はiOS8のセッション聞きたいし別にラボはいいかな。。」と日和りそうになったものの
同じラボの前を「やっぱやめようかなぁ。。」とうろつくこと数回、意を決して再挑戦し、無事BLEのとある問題について聞くことができた!ラボデビュー!これで自分もいっぱしのWWDCerになれた気がします。
— Tsutsumi Shuichi (@shu223) 2014, 6月 3
というわけで質問を全文考えていくことで乗り切ることができました。
あと、事前に @u_akihiro さんが Service Changed キャラクタリスティックの存在を教えてくださっていたので、回答が理解できたというのもあります。(いつもありがとうございます!)
@shu223 そうなんですよね、サービスとかの変更があったら、GAPサービスのとこに変更通知するキャラクタがいて、それで変化がわかると(うろ覚え)GATTは構成変わらないから、iPhoneは積極的にGATTをキャッシュします。
— わふう>ω<のひと (@u_akihiro) 2014, 6月 2
これでもうWWDCの残りを気楽に楽しめます。めでたしめでたし。