その後のその後

iOSエンジニア 堤 修一のブログ github.com/shu223

BLEデバイスと連携するiOSアプリ開発での「落とし穴」についてWWDCラボで聞いてみました

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はラボで質問しまくってこそ価値がある!」と聞いてたので、「ラボで何か聞かないと・・・でも不安だ・・・」(英語コミュニケーション的な意味で)とプレッシャーを感じていました。


でもBLEについて聞けそうなラボはそんなにないので今いくしかない!と部屋に入ったものの、

といったんは逃げ帰りました。


ランチ後、「今年はiOS8のセッション聞きたいし別にラボはいいかな。。」と日和りそうになったものの


というわけで質問を全文考えていくことで乗り切ることができました。


あと、事前に @u_akihiro さんが Service Changed キャラクタリスティックの存在を教えてくださっていたので、回答が理解できたというのもあります。(いつもありがとうございます!)



これでもうWWDCの残りを気楽に楽しめます。めでたしめでたし。