わふうの人が書いてます。

iOSアプリケーション開発、BLEのファームウェアとハードウェア試作のフリーランスエンジニア。

大垣第3回iBeaconハッカソン

第3回目を数える大垣でのiBeaconハッカソンは、本物のバスを走らせて、バス停という日常の場面およびバスという移動体でのハッカソンとなりました。 Facebbokのイベントページ

参加された方のブログなど

会場の写真

Facebookにまとめられた iBeaconハッカソン3の写真 写真。

今回走ったバスとバスの内部写真です。ちょっとした衝撃でした。MOBIUM

MOBIUMは移動を主体とした表現の場です。
大型バスをベースとしており停車可能な場所であればどこでも作品の展示や音楽の公演、映像上映など問わず表現活動を行うことができます。
この移動空間でさまざまな地域に表現活動を届け、地域間の文化交流を行なっていきたいと私たちは考えています。

実験用にバス停にみたてたノボリが用意されました。ハッカソンの文字入りです。ノボリの先端には、3Dプリンタで印刷したケース(選択の黒い筒状の部分)に収納されたビーコンが設置されています。風向きでノボリが回転するので、ビーコンのアンテナの指向性と回転角度が組み合わさって、面白いビーコン領域になりそうです。

室内で実験するために小さなノボリも用意されました。手のひらサイズのノボリの下部に、こちらも3Dプリンタで印刷されたケース(黒い部分)に格納されたビーコンが置かれています。場面にあわせた機械部品を3Dプリンタで作れると、便利なのですね。

会場及び懇親会の様子を微速度撮影したものです。解像度が落としてありますが、皆さんがどのような動きをされていたのかわかります。

第3回iBeaconハッカソン

iBeaconは、Apple社がiOS7で導入した位置と近接検出技術です。
iOS:iBeaconについて
昨年12月に初めてのハッカソンを開催してから3回目を数えるまでになりました。ハッカソンは、”ハック”と”マラソン”を組み合わせた造語で、開発者やデザイナが集まり集中的に共同作業をするイベントを表す言葉です。

第1回iBeaconハッカソン
は本物のiBeaconに触れる体験を、
第2回めのハッカソン
はOnline to Offline (O2O)、オンラインの体験とオフラインの体験が相互に影響しあう時代、をテーマに設定しました。

第3回目
は、本物のバスを走らせて、バス停というありふれた日常の場面そしてバスという移動体を取り上げました。スマートフォンの普及率が高まった今年は、ありふれた日常の場面でビーコン活用が徐々に登場するでしょう。

ハッカソンには、東京からの日帰り参加が難しい大垣という場所ですが、30名弱が集まりました。
iBeaconのビーコンを次々と発表されている(株)アプリックスそしてiBeaconのビーコンとコンテンツ管理システムの統合フレームワークを提供されている(株)ACCESSからも参加をいただきました。第1回目および2回目から引き続き参加されている方が半分弱、新規参加者が半数と参加者の顔ぶれがある程度固定してきたのかなと思います。

第3回目もビーコンは(株)アプリックスから提供を受けました。

プログラム

ハッカソンは午前と午後の部の2部構成です。
午前中に、自己紹介とiBeaconの紹介とバスでの体験を行い午後はアイディア出しと実装を行いました。
お昼及び夕方には、Google GlassとiBeaconの連携や、コンテンツ管理システムのデモンストレーションなど、2回目に参加された方々が作られたものを持ち込まれてのデモンストレーションがありました。

  • 11:00〜12:30:イントロダクションとデモアプリの体験
    • 11:00〜11:30:自己紹介
    • 11:30〜12:00:プレゼン
    • 12:00〜12:30:実際に体験(iPod touch配布)
  • 12:30〜13:30:昼食(お弁当)
    • Googleグラスのデモンストレーション(体験)
    • コンテンツ管理システムのデモンストレーション (2〜3回講演 5分間程度)
  • 13:30〜14:30:チームごとにアイデアスケッチ
  • 14:30〜17:30:実装
  • 17:30〜18:30:体験(日没は17:40)
  • 18:30〜19:00:ディスカッション(GoogleGlassデモ等)
  • 19:00〜22:00:懇親会(近くの居酒屋を予定)

イントロダクション

イントロダクションのプレゼンテーション資料です。

今回のハッカソンは初めて屋外にビーコンを設置しました。写真はB地点にある、今は使われていないバス停の金属柱に貼り付けたビーコンと、そのビーコンの電波が届く範囲(青色の楕円部分)を示しています。ビーコンが出す2.4GHzの電波は金属で反射され、柱の反対側(地図上では北側/上方向)にはほとんど届きません。下方向(地図上で南側/下方向)にはビーコンがよく見通せて50m近く電波が受信できます。

またバスは車体の前と中央そして後ろの3箇所の天井にビーコンを貼り付けました。バスに設置した場合は車体が金属製であること、またビーコンは車外から窓を通して見通せない位置に設置したこともあり、車外にはほとんど電波が出ていきませんでした。バスから5mほど離れると、ビーコンは検出できなくなりました。

ビーコンの設置位置とアンテナの方向および周囲状況で、電波の届く範囲が大きく変化すること、またそれを利用すればB点のバス停であれば、バス停から見て北側(地図の上側)と南側(地図で下側)で異なる表示をさせることもできるなど、リアルな日常でのビーコンの利用場面を設定してみました。

アイデアスケッチ

アイディアスケッチの手順を説明するプレゼンテーション資料です。

アイディアスケッチは、まず、いつ/だれ、を列挙します。つぎに、それをマトリクスにして組み合わせ、自分達が考えていなかった場面を作り出します。そして、いくつかの場面を選びディスカッションと共有をします。

ツール

トリガーデバイス 村瀬 真博 さんが、ハッカソンでも使えるiBeacon検知ツールのソースコードをGitHub上
https://github.com/calmscape?tab=repositories
に公開されています。

チームのプレゼンテーション

5件のプレゼンテーションがありました。

チーム名: カメラ 美大生

バスに乗った時に手荷物があると、荷物をおろしてお財布を出して支払いをしてと手間がかかります。乗降時に時間がかかるので、他のお客さんの待ち時間になったりバスの運行時間にも影響を与えます。そこでバスに設置したビーコンにiPhoneを反応させて、手ぶらで決済する仕組みがあるといいのです。

実際のバスでは多数の乗客がいるので、どの方がいくらの料金を支払うのかを判別しなければなりません。これは、ビーコンの情報を使ってiPadに顔写真を表示して、運転手さんが操作できるようにすれば解決できます。運転手さんは少し大変かもしれない、とのことです。

実際に実験をしてみるて、距離の判定がFarなど思ったような判定結果にならない、またProximityの値は何回かビーコンを受信した結果を平均化してから伝えるため微妙に遅延時間があり、バスで移動する乗客の位置と感覚的にあわずもたつきがある、などを指摘されました。

私の寸評は: チーム名が、おもしろい。カメラが好きな美大生とバスの組み合わせを考えるチームだから、このチーム名になったとのこと。なぜそうなった…

アプリから電波出力を設定することはできないので、iPhoneをビーコンにする構成では物理理的にビーコンの到達範囲を調整することができません。ですが受信側でRSSIの値を直接使うなどの解決方法はありそうです。

バスに限らず、”手ぶらで決済”は日常生活でそれができれば、ものすごく便利です。いまはICカードを取り出して読み出し部分に近づけたり、iPhoneではクレジットカードを取り出して読み込ませるなど、一手間がかかります。顔パス、という支払い場面はとても便利です。

おそらく顔パスのモバイル決済では、支払いと顔情報という重要な個人情報管理が必要になりそうです。ICカードの導入とおなじように、バス会社が支払いのために自社にそのような組織を新設することはありません。外部からサービスを導入するはずです。顔パス決済のような、ビーコンを活用した支払いは、モバイル決済の熾烈なアカウント争奪の戦場になるのでしょうか?

このチームのプレゼンテーションは、さらにもう1つありました。目の前でバスが発射してしまった時は、バズーカ型のデバイスをばすーんと撃つと、そのバスが次のバス停で停車する、というサービス?です。バズーカ型のデバイスにビーコンが仕込まれていて、その信号をバス運転手が受信してバスが停まります。バズでHappyに、とのことでした。

すぐ目の前にバスがいるのに次のバス停まで自分が走って移動するという、ツッコミどころを用意していただきました。イタズラでバスを停める人がいるのでは?という質問をすると、バズーカ型デバイスを押した時に決済処理をして集金をしているので、問題にはならないだろうとのことでした。意外と考えられています。

前方右側チーム

前方右側チームはビーコン検知で音声アナウンスが流れるサービスです。例えばお店に入ると商品の動画を見たりできます。
バス内では、アナウンスを動画や音声で取得ができます。
アイディアノートは、視覚にハンディキャップがある方の場面を考えられていました。しかしデモンストレーションは誰もが使うようになるだろうものでした。

私の寸評は:
このチームの方々は1回目から参加されている方々なのですが、本当に短時間で実装をしてしまう人達なのです。その動いている場面は、文章ではまず伝わっていないと思います。

このデモンストレーションでもGoogle Glassにアプリケーションを実装してビーコンに反応して動画が再生される仕組みを作り、それを実際に使っていました。身につけているしか、わからないよw

装着して使っている人を外部から見ていて、提示すべき情報の取捨選択が必要なのではと思いました。日常の毎日の場面で同じ情報を聞かされては、不快感にならないだろうかと思ったのです。ですが、思い出してみれば電車でもバスでも、同じ目的地や駅名のアナウンスを繰り返し聴いているのが日常で不快ではありません。この体験は気がつけば自然と日常に溶けこんでいそうです。

チーム名 不明 (すいません、チーム名を記録していませんでした)

寸劇でのデモンストレーションです。お酒を飲んでバスに乗り書類を忘れてしまいました。とても大切な書類で目が覚めた時には大慌てです。

バスに乗ったことを思い出して営業所に電話をしました。営業所の方は、落し物の届けはあります、どの時間にどの路線に乗られたかを教えてもらえますか?と言います。ですが泥酔していたので、乗ったバスがわかりません。仕方なくバスの営業所まで直接出向くことになりました。

バスにビーコンが設置されていれば、iPhoneにどの時間にどの路線のどの区間のバスに乗ったかを自動記録しておけます。その履歴をみれば、どの車両にいたかまでを営業所の方に伝えることができます。

そして、そのデータ自体がその場にいた証明に使えます。サーバに情報があるならば参照番号を連絡する、iPhoneにしかデータが保存されないならば画面を営業所の方に送るなどができます。営業所の方が書類の所有者であると確認ができれば、わざわざ営業所に行くこともありません。

プレゼンテーションの最後は、AR.Drone (iPhoneで操縦されることで話題になった、4つの羽があるヘリコプターのような飛行物体、クアドロコプター) で書類を配送すればいいよね、で終わりました。

私の寸評は:
ボケでいくかまじめに語るかで悩んだのですが、ボケとしては、手首に紐でくくりつけておけばいいのでは?、などがあります。

このデモンストレーションには、ビーコン活用の要素が組み合わさっていて面白いと思いました。バス会社は、ユーザがどこにいたかという絶対位置ではなく、どのバスに乗っていたかという情報があれば忘れ物の所有者確認ができます。そして、ビーコン領域検出であれば、おそらくGPSよりも電池消費量は小さいでしょうから、どのバスにいたかの常時監視ができそうです。

子連れiBeacon

子供連れのお母さんがバスに乗る場面を考えました。バス会社がだすアプリケーションを使うと、バス停付近でバスの混雑度合いがわかります。もしもバスが満員であれば、タクシーを呼ぶ機能がついています。

ですが、もしもタクシーも来ないのであれば、混雑しているとわかっていてもバスに乗るしかありません。そんなときには、バスの中のユーザがインストールしているアプリケーションが反応して、子連れの方が乗車されるから詰めてくださいと、端末から声が出て周りの方がどいてくれます。

私の寸評:
子供がいるならみたらいいじゃん、と最初にツッコミましたが、混雑した車内で小さな子供さんが見えるわけがありませんでした。独身者なのですが、そういった視点がなく、さて何を言えばいいのやらと、すこし途方にくれました。

自分にもハイキングの下山時にバスが満員で苦労した思い出がありました。その日最後のバスなので、なんとかして乗せてもらうほかなかったのですが、幸い1人だったので入り口の隙間に入れてもらって下山できました。

子供がいると、そんな場面が日常で大変なのだろうと思います。なかなか声に出して自分で詰めてくださいとはいいずらく、また運転手さんが気づいてくれるとは限らないでしょうから、その気まずさをビーコンとユーザが持っている端末の組み合わせで解決できれば面白いと思いました。

じゃんけん大会

ちょうどこのハッカソン開催日 2月26日 が出版日の
秀和システム iOS位置情報プログラミング iBeacon/GeoFence/Navi/CoreMotion/M7の理解と実践 の著者 橋本佳幸 さんがハッカソンに参加されていました。アマゾンではすでに品切れになっている著書を、じゃんけん大会の勝者たちにプレゼントされました。

iOSアプリケーションで位置情報を取得する方法はApple社のプログラミングガイドに詳しく書かれていますが、実際に使われるアプリケーション開発には、さらにコンテンツ管理やデバッグなどの実務が求めるスキルとノウハウが必要です。ちょうどO2Oやマイクロロケーションの活用が広く知られだしていますが、そのようなヒトとモノを繋ぐサービスの開発の、実務としての役立つ情報が満載です。

ハッカソンを振り返って

かなり難易度の高い設定だったと思います

3回めのハッカソンは、初めての屋外でのビーコン活用であり、さらにバスという移動体やバス停という場面まで設定して、かなり難易度の高い場面設定をしたいと思います。2回めの屋内での利用であれば、ビーコンに反応してiPhoneに何かが表示される、という利用方式で、その表示内容や人々のやりとりでストーリーを作れました。

ですが3回目の設定では、専用のアプリケーションを開発しなければデモンストレーションの場面を実際に見せることはできないケースが多かったと思います。その中でも、前方右側チーム はGoogle Glassとそのアプリケーションを作り、各チームもストーリをねりこんだプレゼンテーションでした。

1回目から続けて参加されている方々が半数で、スキルが高いことはもちろん、ビーコンの利用やハッカソンに熟練されてきたのかなと思いました。

事故がなくてよかった

各チームごとの、屋外およびバスに乗ってビーコンの電波強度の計測をしていました。バスの移動経路に、交通量が多い道路があったため自転車や自動車との接触事故が起きないかと不安があったのですが、さいわいそのようなことはなく、無事にハッカソンを終えることができ、ほっとしました。

お気軽に参加ください

30人を超す人が集まり作業ができる場は、なかなか準備が大変です。勉強会などで特定の会社がその場を提供している場合をよく見ますが、それでは他社の方が参加しづらくなるかもしれません。

このハッカソンは岐阜県の協力で成立しています。学会のようなプレゼンテーション専用の場でもなく、かといって情報交換の場でもない、お互いの知識と経験をもとに互いに話し合える機会を、へんな色なく提供していると思います。活用ください。

次回は…

3月終わりから4月にかけて、第4回iBeaconハッカソンを企画しています。また、そんな場所を使うのかといいましょうか、なんといいましょうか。面白い場面設定になると思います。

謝辞

会場の手配またハッカソンの企画および運営は、IAMAS 准教授 小林 茂さん、そしてトリガーデバイス佐藤さん、MOBIUM の尽力によるものです。

トリガーデバイスは 近づくだけで美濃観光案内 近距離通信規格を用いスマホに のビーコン設置とアプリケーション開発も担当されています。今回のハッカソンでビーコンの振る舞いを確認するアプリケーションも提供を頂きました。

このような時間と場を設けていただいたお二人に、また資材や場所を提供いただいた(株)アプリックス、(株)ACCESS、岐阜県の担当者の方々、そして参加された皆様に、重ねて感謝いたします。

iBeaconハンドブックの下書き

このブログに長らく下書きを掲載していたiBeaconハンドブックを、Kindleストアで出版しました。
本書をまとめるまでの事業、講師や講演またハッカソンに呼んで頂いた方々、またハッカソンに参加された方々に感謝します。

1月29日 大垣 第2回iBeaconハッカソン

いただいた紙の名刺をスキャナで取り込みながら、第1回iBeaconハッカソンに出ていた、ビーコンのある領域に一定時間一緒にいた人たち間で、名刺的なデータを自動記録できるアプリケーションでも作っておけばよかったと、今頃思っている(同)わふうの上原です。

会場の写真、参加された方のブログ

第2回iBeaconハッカソン

iBeaconは、Apple社がiOS7で導入した位置と近接検出技術です。単語として話題になるiBeaconですが、ビーコン体験の実際とその体験談を交換しあう場として、昨年12月に(おそらく世界初、確実に日本初)のiBeaconハッカソンを開催しました。ハッカソンは、”ハック”と”マラソン”を組み合わせた造語で、開発者やデザイナが集まり集中的に共同作業をするイベントを表す言葉です。

第1回iBeaconハッカソン http://reinforce-lab.github.io/blog/2013/12/18/ibeaconhackathon/は、iBeaconの体験を通して自由な場面想定をしました。ビーコンというガジェットと自分、あるいはガジェットと周囲にいる人という場面でのアイディアが多く出ました。

第2回めは2014年1月29日に第1回と同じ岐阜県大垣市 ドリーム・コア2Fメッセで開催されましたイベントページ: https://www.facebook.com/events/628415297227268/

第2回めは、あえて単語として話題になってきているOnline to Offline (O2O)、オンラインの体験とオフラインの体験が相互に影響しあう時代をテーマに設定しました。第1回で提供した技術の理解と実際の振る舞い体験を糧にして、道具としてのiBeaconが未来にどのような形で一般世間に溶け込んでいるかを体験するのが狙いです。

ハッカソンには、東京からの日帰り参加が難しい大垣という場所ですが、30名弱が集まりました。第1回に参加された方が半数、今回第2回めに参加された方が半数という感じでした。2回めは1回めよりも経営者や企画そして大手やベンチャーで、業務としている方やこれから事業を立ち上げる方が多く参加されていました。技術という手段ではなく、道具としての技術手段に興味を持っていただきたい狙いに、反応して欲しい立場の方々が集結されたのだと思います。

第2回も、ビーコンは(株)アプリックスから提供を受けました 岐阜県、iBeaconハッカソン(第2回)を開催 http://www.aplix.co.jp/?p=8240

プログラム

ハッカソンは午前と午後の部の2部構成です。午前中に、自己紹介とiBeaconの基礎、そしてPassbookのプレゼンテーションを通して知識を共有しました。

  • 11:00〜12:30:イントロダクション+iBeaconとPassbook連携レクチャー
  • 12:30〜13:20:昼食(実店舗でのiBeacon体験)
  • 13:20〜14:30:施設内でのiBeacon体験
  • 14:30〜18:00:グループ毎にアイデア出し、実装、テスト
    – アイデアスケッチセッションの説明:10分
    – だれ/いつのマトリクス(デザインパターントランプを使って):20分
    – アイデアスケッチ:30分
    – 実装とテスト(前半):60分
  • 進捗の共有、実装とテスト(後半):90分
  • 18:00〜19:00:各チームの実装したものの体験とディスカッション
  • 19:00〜22:00:懇親会

このように内容をぎっちり詰め込んだタイム・テーブルでしたが、時間通りに進行しました。進行を担当された小林先生と参加者の方々のレベルの高さがすごかったです。

お昼ごはんは、ソフトピアジャパン1階のレストラン、こみゅれす美濃味匠で、iBeaconでPassbookを反応させて割引クーポンを出して、ワンコインランチを注文する体験をしました。これは、割引クーポン(割引費用)の提供とレストランへのビーコン設置と注文受け付けの対応など、(株)デリカスイトの提供と協力で実現しました。

午後はiBeaconの振る舞いを体験した後、チームに分かれてアイディアスケッチとディスカッション、そしてビーコンに反応するコンテンツを作り、デモンストレーションを行いました。

ビーコンに反応するコンテンツを作れるiOSアプリケーションは、(有)トリガーデバイスから提供されました。提供されたアプリケーションは、館内地図にビーコン配置が表示され、訪問したビーコンの表示変化およびコンテンツ表示をするアプリケーションで、コンテンツをDropbox経由で更新できるものです。

イントロダクション

イントロダクションのプレゼンテーション資料です。

最初は上原がiBeaconの概要をプレゼンテーションしました。Slideshareにアップロードしたこの資料はよそ向きですが、実際のプレゼンテーションは”ぶっちゃけ話”を入れていました。

プレゼンテーションでは、O2Oという単語は様々な人がそれぞれの文脈で使うため定義があやふやでわからない、と切り出しました。そこでO2Oという単語はあえて忘れて、2年後の(O2Oっぽい)日常を想像してみよう、と提案しました。その日常を支えているビーコンなどの設備、そしてコンテンツを作り配布する会社やサービス提供会社がどのようなものか、その日常に至るまでの2年間の経緯を具体的に想像することを、提案しました。

次のPassbookのプレゼンテーションは、ユーザが手軽にPassbookを使えるサービス、パスタhttp://passta.jpを展開されている、株式会社モノプレーン代表取締役 小西 啓一郎さんにお願いしました。

O2Oと気軽に口にしますが、実際に何十万ものパスを発行してきたいくつもの経験談に目と耳が釘付けになりました。リアルな話を1つ1つ、何が起きたかとその理由と分析を交えた素晴らしいプレゼンテーションでした。

例えば、パスの更新をかけるとユーザのiPhoneが一斉に反応して、一瞬で何万ものアクセスがサーバにきて更新に支障がでるなど、現象と原因を聞いていれば確かにそうなると納得もするし、そして、ぞっとする話でした。

アイデアスケッチ

アイディアスケッチの手順を説明するプレゼンテーション資料です。

アイディアスケッチは、まず、いつ/だれ、を列挙します。つぎに、それをマトリクスにして組み合わせ、自分達が考えていなかった場面を作り出します。そして、いくつかの場面を選びディスカッションと共有をします。

ディスカッションの中休みで寸評を入れました。私は、ユーザがiPhoneを手に持ちアクションが起きるようなネットと変わらぬ1人で閉じた場面は、つまらないと思いました。想定場面で、リアルだからある相互のやりとりが欲しいと思いました。

例えば、店頭でのO2Oでは必ず店員さんの存在があります。ですからレジ前でのポイント発行も、ユーザがiPhoneをかざしたらポイントが得られるような一人芝居ではなく、例えば巨大なぬいぐるみのスタンプにビーコンを入れておき、店員さんがスタンプを押す演出をしてはじめてポイントが出るなら、楽しいかもしれないと思います。

単純に電波を出し続けるだけのビーコンでは、このような相互作用の演出は困難です。先ほどの例であれば加速度センサでスタンプの動きを検出して適切なタイミングで電波を出す追加機能が必要でしょう。iPhoneはアプリを作ればビーコンになりますし、加速度をはじめとして高度なセンサーをいくつも搭載しています。iPhoneでアプリを作れば、先ほどの演出のプロトタイピングができます。

チームのプレゼンテーション

6チームが、それぞれのアイディアと成果をプレゼンテーションしました。

最初のチームは、”いつもの。”という初めてのお店でも、自分の”いつもの”が注文できるサービスです。自分の顔写真と好みのメニューをiOSアプリケーションに登録しておきます。自分のiPhoneが、お店に設置されたビーコンに反応して、自分の顔写真と”いつもの”情報をお店側に表示します。

チームに大阪の方がいはるのにボケどころがなく、プレゼンテーションは美しく利用場面は王道でした。私は不正なチート/いたずら行為を散々指摘しようと手ぐすねを引いていたのですが、隙がなく、ぐぬぬぬぬ、となりました。

2つ目のチームは、特定の人だけに情報を伝えるための鍵にビーコンを利用するもの、でした。iPadのロック画面には4桁のセキュリティ・コード入力がありますが、まだ小さい自分の子供が画面の指紋の跡を見てそのロックをはずす体験談を交えたデモンストレーションでした。

iBeaconの情報はブロードキャストしているが鍵になるか? のツッコミに、UUIDがランダムに変化する、その時間にしか使われない鍵的なUUIDを実装すればよい(だたか?記憶がおぼろげで、勘違い/思い込みしているかも)。また外装が鍵っぽいものがいいよね、そんなやりとりでした。

3つ目のチームは、外国人の方をターゲットにした、レストランのレビュー記入の場面でした。Trip adviserのような、旅の口コミ・サービスのアプリケーションへの追加機能を想定しています。サービス対応を示すステッカーが貼られているレストランでアプリを起動すると、ビーコンに反応してレビューの記入画面が表示されます。

すでに普及しているサービス/アプリケーションに追加するのは、多くのユーザの獲得と利用の広がりが期待できます。またビーコンの電波の届く範囲はユーザの視界と重なりますから、アプリを開いたらそこに目の前に見えているお店が表示される自然な体験も作れるでしょう。ユーザ操作の手間をゼロにできるのは、小さいように見えて、大きな効果がありそうです。

看板にビーコンを仕込んでおいて、店頭に設置している間は電波が出るしかけを入れて、開店時間だけ反応させるなど、ビーコン側の工夫もできそうで面白そうだと思いました。

4つ目のチーム名 party peopleは、顔はわかるけどこの人は誰なんだろうという場面に、その人が持っているビーコンから情報を得るというサービスです。ビーコンを胸から下げるカード形状にしたり、電波の指向性や強さの設定機能をサービスに活用する提案を出されました。

イメージとしては、北斗の拳で戦闘時に身にまとうオーラのように、その人がまとう見えない気のようなもの、の活用場面とのことです。

すれ違い系や出会い系などの応用場面と構造が共通しているのですが、その人の雰囲気、というテーマはiBeaconの利用場面として面白いのです。ですが、面白すぎて、ネットでは”プライバシーが”という前振りで、殴り合いの材料となりがちな定番のお祭り素材でもあります。ビーコンの物理的な特性とサービスの特性をうまく掛け算する、相互影響させる考え方がとても興味を引きました。

ここまで、ツッコミどころがなくて、私はぐぬぬぬ状態です。

5つ目のアニメ大ファンチーム(これがチーム名です)は、お金を持っているリッチなアニメファンの待ち合わせ場面、を想定しました。アニメ素材を持っている方とアプリ開発ができる方がチームにいたとのことで、実際に萌えるアプリを作ってのデモンストレーションです。

文章ではデモンストレーションの雰囲気を表現しづらく、写真を掲載すれば伝わるとは思うのですが、それは諸事情でためらうので、要点を書いてみます。

ある地点Aに行くとビーコンに反応して、”もぉ、おそいじゃない、30分も待ったわ、ぷんぷん”とアプリ内のキャラクタが対応します。ビーコンにタッチすると、セリフが変わります。そのような出会いをビーコンが設置されたいくつかの場所で繰り返すと、あるお店で”この服がほしい”というおねだりイベントが発生します。

お店でリアルに服を購入するとフラグが立ち、秘密の場所(建物最奥の人気がないひっそりとした場所に設置されたビーコンを利用されていました)で、最終イベントが発生します。強烈な印象で他のチームのプレゼンの記憶がすべて吹き飛ぶかと思ったほど、デモンストレーションがのりのりでした。

ツッコミどころがありすぎて、負けたorz状態です。

最後のチームは、郊外に住む節約大好きの働く主婦を想定しました。この方は、バスで仕事場に通勤をしていますが、勤務時間の都合でタイムセールに間にあわないことを日頃不満に思っています。そこで名鉄バスと名鉄パレが運営するスーパーマーケットがグループとして手を組みます。

朝の通勤時に、バス停でアプリを表示すると今日のチラシが出てきます。その場で予約、決済をするとタイムセールの価格で購入できます。商品はお取り置きとなり、帰り道にスーパに立ち寄り商品を受け取ります。

さらに通勤中のバスにもビーコンが設置してあります。そのビーコンがトリガーになり、バスに乗っている人に”あんぽ柿、今なら半額、残り時間x分”と表示されます。これもその場で購入決済すれば帰りに店で受け取れます。しかし、購入するかどうか悩んでいると、その間もバスは進みます。そして”あんぽ柿は完売です”と表示が出てしまいます。

最後に、お仕事場につくと、お仕事場にあるビーコンが反応して、お仕事がんばってください、受け取りも忘れずに、と表示が出ます。

むちゃくちゃ王道ですし、日常場面で自然にあるあると思えて、ツッコミというよりむしろ次回の実験/体験にしましょう、と前のめりになりました。

もう負けでいい、と思う状態です。

ハッカソンを振り返って

王道の構造を捉えていました

計6チームによるプレゼンテーションは、どの内容も日常の場面で、かつチート行為のツッコミどころがなく、そしてプレゼンテーション資料もデモンストレーションもいずれも素晴らしいものでした。

ツッコミどころがありません。

iBeaconでのチート行為は、ビーコンが簡単に複製できる性質によるものです。ですから、ビーコンを使うことでその場その時間でしか得られない体験を作っても、それがネット側の反応だけで完結する構造であれば、容易にチート行為ができます。

しかし、6チームはすべて、フローのなかにリアルな世界や店舗との関わりが入っていて、その関わりを経ていないと意味がない構造です。これがその場にいないユーザが不正に利益を得ることを不可能もしくは無意味にしています。

6番目のチームのタイムセールのケースは、最もチートしやすく思えます。ですがこれはチラシの配布とタイムセール(割引販売)による集客が本質です。そして販売決済というフローが入っていますから、不正にビーコンをコピーしてそのタイムセール品を購入しても問題になりません。

まいりました。

枠を超えて

第1回は自社あるいは自分で出来る方々が多く集まられていました。その方々は、おそらく自社/自分で製造販売企画設計流通経営財務労務宣伝広告サポートができ、思った通りに思ったことを進められると思います。その流れは、それでいいと思います。

しかし、今回取り上げたテーマO2Oは、日常生活に溶け込んだiBeaconのある世界です。そしてその世界は、Appleのように大きな会社であっても、1社の行動だけで到達できる世界ではありません。iBeaconだけを見ても、ビーコンの製造設置運営、コンテンツの作成と配布、そしてサービス提供する会社とiBeaconを営業に活かす経営判断をする依頼主が、その世界の構成要素に必要です。

このハッカソンが、そのような未来の日常を共有して、お互いの立場や経験や業界を知り、会社の枠を超えた協業で共有した未来に到達する、そのきっかけづくりの場となればと思います。

実験と社長への売り込み

今回のハッカソンで一般のレストランでのパス配布を実施しましたが、この小さな実験でもいくつかの経験が得られました。小さな実験を何度も繰り返していくことが大切です。

このハッカソンの未来は現実になるのでしょうか?予算をつけて現場で運用すると判断する人がいれば、技術的にはYESです。このような性質の商品は、現場の担当者に売り込むものではなく、社長に売り込むものでしょうし、そのような売り方ができる人達が鍵になるのでしょう。

またアプリケーション開発などのコストも必要です。そのような予算を広告宣伝として出せるところとなると、ブランド力があり自社製品のイメージを制御している会社が、最初の取り組みによる話題性と経験の蓄積を狙い取り組むのかもしれません。

一般スーパーのような分野は無視すればいいでしょう。NFCやRFIDといった技術が切り開く未来が夢として語られ未だに夢である現実を見ると、先進的な取り組みをするとは思えません。

ビーコンは盗まれるのだろうか、またそれで困るのだろうか

レストランの小さな実験を見ていて、ビーコンは盗まれるのだろうか、またそれで困るのだろうか、と思いました。

よくレジの横に提携クレジットカード会社のロゴが印刷されたプラスチックの置物がありますが、あれはどの程度の頻度で盗まれるのでしょうか。ビーコンが盗まれる頻度は、そのクレジットカードのプラスチック標識と同じ程度でしょう。

ビーコンの管理システムでビーコンが盗まれると困るから検出機能が必要だと思うこともありますが、では盗まれると何が困るのでしょうか。ビーコンは容易にコピー可能である性質を考慮して、チート行為などの対策はするはずです。ですから盗まれたビーコンでのチート行為は、盗む、という行為とは無関係です。サービスが停止することが、困ることでしょう。

小さな実験を経験してから振り返ると、現実が見えてきそうです。

iBeaconと日常生活

ものxiBeaconの組み合わせはO2Oでも面白い場面があると思いました。店舗へのビーコン設置では、照明にビーコン機能をもたせるアイディアは有効でしょう。光が当たる範囲と電波が飛ぶ範囲を合わせておけば、可視光通信がよく提唱していたように、人間が目に見える範囲と電波の範囲が一致するので運用が楽になるでしょう。

せっかくBluetooth LEの技術を使うのですから、ついでに無線調光機能も入れるといいでしょう。Bluetooth LEの機能を追加することで照明の単価が上がりますが、LED電球の10年単位の長い寿命が、それを補ってくれるでしょう。

決済と物流

iBeaconを話題にするとき、O2O、決済という2つの単語といっしょに取り上げられることがあります。iBeacon自体は位置と近接の検出技術にすぎず、O2Oも決済もサービスですから、その取り上げ方はよい語り口ではないと思います。

ですが、iOS7で導入されたP2P通信、Remote Notificationも視野に入れれば話は別です。なぜこの技術が一般アプリ開発者に公開されているのか、それが可能にするサービスはなにかを考えることは重要です。

お気軽に参加ください

30人を超す人が集まり作業ができる場は、なかなか準備が大変です。勉強会などで特定の会社がその場を提供している場合をよく見ますが、それでは他社の方が参加しづらくなるかもしれません。

このハッカソンは岐阜県の協力で成立しています。学会のようなプレゼンテーション専用の場でもなく、かといって情報交換の場でもない、お互いの知識と経験をもとに互いに話し合える機会を、へんな色なく提供していると思います。活用ください。

消費されるビーコンと消費されないビーコン

前回のハッカソンが個人とiBeacon、今回のハッカソンがサービス提供会社と消費者の組み合わせとiBeaconという構図でした。いずれのハッカソンでも、ビーコンは建物に設置されたり、ユーザや店舗が所有したりと、持ち続けられるパターンのものです。

一方で、ものxiBeacon、として現実のものにコンテンツを紐付ける手段として見るならば、例えば店舗によく設置される幟や看板に埋め込むなど、消費されるビーコンのパターンもあります。iBeaconの特徴は、電波が出ることではありません。ユーザが持っているiPhoneが受信機になり、しかもバックグラウンドで動作するアプリケーションを通してユーザに能動的に働きかけできることです。

消費される電子部品という構図は、例えばパチンコ産業が参考になるでしょう。パチンコの遊技台には液晶とプロセッサが使われ頻繁に廃棄購入されるので、電子部品メーカーにとって無視できない市場規模になっています。

消費されるコンテンツといっしょに紐付けに使われるビーコンが消費されるパターンは、次回以降のハッカソンで取り上げたいテーマです。

次回はバス

2月末から3月初めにかけて、第3回iBeaconハッカソンを企画しています。

3回めは、バスを1台用意して、ソフトピアジャパンの周囲の道路を巡回してもらい、そのリアルな生活圏の中でハッカソンをします。また路線バスのバス停に、ビーコンを設置する予定です。

私も話を聞いた時は、えっそんなことができるのですか?、と思いましたが、小林先生と(有)トリガーデバイスの佐藤さんが、それを実現されました。むちゃくちゃだぁと思うのですが、ものすごくワクワクしています。

東京でiBeaconの話をしている時に”電車の中に設置したらどうだろう、じゃJRに売り込みに行こう”みたいな話が出たことがあります。しかし実際に東京でそのようなトライアルをすることは、社長の鶴の一声でもなければ実現しないでしょう。

岐阜県、おそるべし…

謝辞

会場の手配またハッカソンの企画および運営は、IAMAS 准教授 小林 茂さん、そしてトリガーデバイス佐藤さんの尽力によるものです。

トリガーデバイスは 近づくだけで美濃観光案内 近距離通信規格を用いスマホに のビーコン設置とアプリケーション開発も担当されています。今回のハッカソンでビーコンの振る舞いを確認するアプリケーションも提供を頂きました。

イントロダクションではPassbookについて、ユーザが手軽にPassbookを使えるサービス、パスタhttp://passta.jpを展開されいる、株式会社モノプレーン代表取締役 小西 啓一郎さんにプレゼンテーションをいただきました。

お昼ごはんのPassbook割引チケットは、ソフトピアジャパン1階のレストラン、こみゅれす美濃味匠を経営されている(株)デリカスイト http://www.delicasuito.co.jpに提供をいただきました。またレストランへのビーコン設置と会計時のパスの扱い手順などの打ち合わせ、そして当日の運営にご協力を頂きました。

このような時間と場を設けていただいたお二人に、また資材や場所を提供いただいた(株)アプリックス、(株)デリカスイト、岐阜県の担当者の方々、そして参加された皆様に、重ねて感謝いたします。

O2OでのiBeacon活用のデザイン・パターン

O2O(オーツーオー)は、オンラインとオフラインの購買活動がそれぞれ連携/影響しあう、またオンラインでの活動が実店舗での購買活動に影響をすることを示す用語です。出典 http://www.sophia-it.com/content/O2O

ネットワークと常時同期するスマートフォンが普及した今日では、もはやオンラインとオフラインを区別する意味はありません。経済活動の主体となる個人を軸にすえれば、スマートフォンや実店舗は、購買の手続きや支払いの窓口や、受け取り場所といった手段にすぎません。

ここでは、iBeaconがO2Oでどのように活用できるか、また逆に、O2OでやりたいことにiBeaconが使えるか、を考えるうえで押さえたい項目を列挙します。

基礎知識

iBeaconはなにか、その原理とiOSでの振る舞いは、スライドを参照してください。

iBeaconは、Appleの登録商標で、領域と近接の検出技術をしめす言葉です。電波を出すビーコンがあり、iOSはビーコンの電波を監視して、ビーコンの領域に入った/出たをアプリケーションやパスブックに通知します。

iBeaconは単なる領域と近接の検出です。これを使いアプリケーションを作れば、
例えば決済やカタログ表示など、位置に紐付いたサービスを提供できます。

ビーコンはUUID(128ビットの識別子)、major番号(16ビットの符号なし整数)、そしてminor番号の情報を電波に乗せて、周囲に送信しつづけるものです。iOSのパスブックおよびアプリケーションは、ビーコンの監視にUUIDを必ず指定しなければなりません。つまり、ビーコンのUUIDを事前に知っていなければなりません。

また、ビーコンが多数同じ場所にあっても、互いの電波がぶつかったりして、ビーコン信号が検出できなくなることは、ほとんどありません(1つの場所に100個以上のビーコンがあれば、すこし衝突するかもしれませんが)。ですから、同じ場所に思い思いに多数のビーコンを配置しても、混信してビーコン信号が検出できなくなったりは、しません。

デザインパターン、その1

エリア

iBeaconは領域と近接の検出技術です。そのビーコンの配置と建物の構造を組み合わせます。

ゲートは、入り口の領域をビーコンで覆います。この入り口への出入りを検出できます。エリアは、どの領域にいるか、またどの領域からどの領域に移動したかを検出します。最後のスポットは、例えばレジの周囲でのみイベントを起こしたいときには、そのスポット領域を覆うようにビーコンを設置します。

ビーコンを出している時間

ビーコンの電池は、24時間電波を出し続けても、数年程度連続動作します。ですから、ビーコンは電波を出し続ける設定で、どこかに設置して利用します。ビーコンのハードウェアの内部にあるマイコンで、ファームウェアという小さなプログラムを入れることができます。ですから、ビーコンの発信を決まった時間に設定したり、あるいはいまビーコンを出したい/止めたい、という操作ができるビーコンも、作れます。

検出のタイミング

iOSがビーコンの電波を検出するタイミングは、3つあります。1つはロック画面が表示された瞬間です。例えばiPhoneをポケットから取り出して、ホームボタン/スリープボタンを押した瞬間に、ビーコンの電波をチェックします。2つめは、アプリケーションのバックグラウンド状態です。iPhoneの画面が表示していない間も、領域を監視し続けるアプリケーションが作れます。3つめは、アプリケーションのフォアグラウンド状態です。バックグラウンド状態で取れない、ビーコンとのおおよその距離(10m程度のばらつきがある)まで取得できます。

作用

ビーコンを検出した時に、iPhoneからユーザになにかしらの影響を与えられます。アプリケーションがバックグラウンドでサーバと通信するだけのように、ユーザにはなにも影響を与えないこともできます。ロック画面に通知を表示したり、電話着信のように音や振動をだすこともできます。またユーザが画面を見ている時であれば、画面の上に通知を表示したり、またアプリケーション自体が実行されているならば、画面に何かを表示することができます。

モチベーション

iBeaconの話題の多くは、売り込む側の人たちや大手流通を想定した、もっと儲かりますと主張する場面説明でうめつくされています。しかし、大切なのは、iBeaconを利用する側の動機です。例えば、ビーコンの領域に入った時に、割引クーポンを発行することができます。また、買い物の場面であれば、自分にあったサイズの商品がどれかをお知らせすることもできます。売り手が買い手に主張するほかに、ユーザ自身がやりたいことをできる場面も多くあります。例えば、牛乳を買おうとメモをしていれば、牛乳がどこにあるのか、教えてくれる仕組みも作れます。

デザインパターン、その2

表の目的、裏の目的

ユーザに、こう使ってくださいという説明と、その使いかたをすると副次的に得られる情報を別の用途につかうことも、規約とユーザの受け取り方や感情に問題がないならば、できるでしょう。例えば、広大なショッピングモールでお目当てのお店までナビゲーションを提供するアプリケーションがあったとします。どの経路を通ったかをサーバとやりとりしていれば、ユーザの移動経路はサーバ・ログに残るでしょう。そのログには、仕入れや売上計画を作る基礎データとして、解析する価値があるでしょう。また、ビーコンを利用した支払いやクーポンの利用履歴は、サーバに記録が残ります。いつ、だれが、なにを購入したかは、仕入れ計画や商品開発に役立つ貴重な情報です。

商品の性質

iBeaconとO2Oとを商品販売に活用する場合、その商品が、いつどこで購入できるものかで、ビーコンの活用方法が異なります。
例えば、工芸品や季節の果物など今この時しか購入できない一品物の商品は、その商品が欲しくて買いたい人と商品の出会いを作ることになるでしょう。
自社のオリジナルの商品群をもち、オンラインと実店舗それぞれで販売をしているならば、実店舗はショールームとして、商品を体験できる場に特化していくかもしれません。
また本やCDなど、どこで購入しても同じ商品が手に入るものならば、納品予定日と価格、そして故障対応などのアフターケアと、価格を比較して、たとえ目の前に商品があっても、別の場所で購入するかもしれません。
それぞれの場で、ビーコンの活用場面はあるでしょうが、その活用方法は異なるでしょう。

更新をかけるところ

パスブックをつかうにせよ、アプリケーションをつかうにせよ、実店舗と連携してコンテンツを更新していくことが重要です。その更新を、いつ、だれが行なうかは、2通りあります。チェーン展開をしている場合は、全体の運営を取り仕切る部署が行うでしょう。また、個別の店舗ごとに、あるいは現場の担当者の判断で、更新をかけたい場合もあります。

UUIDの所有/利用範囲

ショッピングモールなど、ビーコンを利用するがそのデータは一切外部にださず自社内部でのみ利用するならば、UUIDは自社内だけで運用します。決済のように、サービスの利用のためにビーコンを顧客店舗に設置する場合も、サービス提供会社自体がUUIDを管理し、外部に提供することはないでしょう。公共機関やイベント施設であれば、設備として設置されたビーコンを、第3者が利用できるようにルールを作るかもしれません。

デザインパターン、その3

動作環境

データが全てiPhoneにあるならば、ビーコンとアプリケーションのみで、ローカルで閉じた利用ができます。3GやWiFiが使えない場所や、WiFiが利用できない場所でiPod touchで運用したい場合には、これを選択します。またロギング系であれば、アプリケーションからクラウドに、データを送ります。コンテンツを更新するものであれば、クラウド側と通信をして、ローカルのデータを更新します。

購入と利用の流れ

O2Oという単語では、これは重要だと思うのですが、商品やサービスの購入のタイミングと利用するタイミング、あるいは購入から利用までの流れで、ビーコンの活用方法が異なります。実店舗は、目の前に商品があり、それに触れることができます。そして購入できます。もしもショールーム化した店舗であれば、実店舗で購入手続きを行い、宅配便で後日配送されます。航空券や宿泊施設は、購入と利用タイミングがずれます。オンラインなどの手段でまず購入して、実店舗で利用します。購入時に入力した情報と実店舗での利用者をひもづけるために、アプリケーションを使うならば、簡便にアプリケーションを表示するためにビーコンを利用するのもいいでしょう。

ペンと紙は強い

モバイル、あるいは自動化の仕組みがあっても、それを運営するのは人間です。
そして人間が理解できるものは、ペンと紙でできること、だと思います。

電車に乗る場合でも、スマートフォンで予約してICカードで入場する人がいる一方で、切符を窓口で購入して切符で入場する人もいるように、利用者視点での手段の提供が求められます。

デザインパターン、その0

ロック画面を表示した時に、iOSはビーコンをチェックします。実店舗にビーコンを設置しておくと、そのビーコンの周囲でロック画面を表示した時に、実店舗に該当するパスブックやアプリケーションをロック画面に表示させられます。今いる場所に紐付いた自然な表示方法として、これを活用できます。

たくさんあるパスやアプリケーションをいちいち起動するのは、大変な手間ですし、支払いのためにユーザがアプリケーションをレジ前で探していては、レジに長蛇の列ができてしまいます。

パスブックとアプリケーションの使い分け

パスブックとアプリケーションの使い分けは:

  • 1画面を表示するだけの機能ならばパスブック、その他の機能を提供するならアプリケーション。
  • ロック画面に、ビーコンがあれば表示すればよいパスブック、表示する/しないをiPhone内部で判断させたいならばアプリケーション。

とします。パスブックは、Appleの審査は不要で、電子メールなどで配布ができ、コンテンツの作成も楽で、安価です。アプリケーションは、任意の処理を盛り込めますが、AppStoreの審査をうけて一般配布ができます。開発費用がかかります。

心地よさと不快感

iBeaconの活用場面を考える時、ユーザに心地よい印象を持ってもらえるか、不快にならないか、を検証します。例えば、店舗の前を通過するだけで通知が表示されるものでは、通勤経路にそのお店があるたび通知が表示されます。これは、電子メールのスパムと同じ不快感を与えて、その店舗に悪印象をもつでしょう。

パスブックは、ロック画面を表示した時にビーコンを検出すると自動的に表示されるため、ビーコンの設置やパスブックの設定によっては、このスパムのような振る舞いをします。ビーコン配置の変更ができない場合は、パスブックではなくアプリケーションを使い、アプリケーション内部で通知を出す/出さないを判断する処理をいれるなどします。

他のビーコンとの比較

iBeacon以外に、音波や光を使うビーコンや、WiFiの電波を利用するビーコンがあります。それらとの長所短所を簡単にまとめます:

iBeaconの長所は、アプリケーションがフォアグラウンドになくてもビーコンを検出できる、ことです。iOSに統合されている強みです。

音波や光を使うビーコンは、マイクやカメラを使うために、ユーザが意識をしてアプリケーションを起動して、さらに読み取り操作を行わねばなりません。また音波は、殆どの人には聞き取れませんが、耳の良い人にはキーンという音が聞こえて不快感を与えることがあります。光は、室内の照明で影ができるように直進性が強く、周囲に一様に情報を拡散する光源の設置には手間がかかります。

WiFiを利用するビーコンは、AndroidとiOSの両方で利用でき、かつバックグラウンドでのビーコン検出も可能です。ただし、最近はWiFiの電波をバックグラウンドで検出するiOSアプリケーションは、AppStoreでリジェクトされるようです。iOSでは、iBeaconと比べて特段に優れた点はありませんが、Androidではビーコンとして今後も使えるでしょう。

iBeaconのビーコン設置とチート対応の一例

もう、よくある例題なので、載せときます。

チート防止でUUIDまでいじるのは、Androidで無法される場合は意味ないんだけど、UUID固定だとiOSで拾われるかもしれないから、UUIDも変えちゃえ、って程度の話。
実際にはCBでペリフェラルに接続かけて、キーをゲット、とかできるのでしょうけど。そこまでやらなくても、運営でカバーしたほうが、楽だと思うし。人がどっと来る場面では、接続ミスとか、いやなトラブルの原因になるし。

iBeaconぶっちゃけ雑感 - これって不動産よね

iBeaconの、ブログ記事を書いたり、講演をしたり、勉強会でプレゼンしたり、ハッカソンが開催されたりと、ひと通り、iBeaconを伝えるべきところには伝え終わったかな、と思うので、ここらでぶっちゃけiBeaconってどうよ?、と乱文を書いてみようかなと思います。

Twitterに散々書き散らしていますが、Twitterではまとめとしてイマイチですので。

ノンアルコールだけど梅酒でお酒を飲んだ気分になって。

iBeaconって、マイクロな不動産なのよ

iBeaconとかいってるけど、せいぜい30mの範囲をマーキングするわけでしょ。犬がテリトリーを主張するのに、おしっこするのと、やってることは同じ。
そして、野生の世界ではテリトリーは命をかけて守ってるから、それくらい価値があるってことよね。iBeaconを設置できたら、つまりテリトリーをゲット、ってことじゃない。

これって、意味付けされたマイクロな不動産が生まれた、ってことだよね。
だって、セブン-イレブンのレジの前10mに並んだ人に、狙い撃ちで広告をうてる権利、っていくらの値段がつくと思う?
iBeaconを設置した人は、自分の商売のためだけに設置するのだろうし、そういうことだと思うけど、
でもUUIDはスニフしたらわかっちゃうし、毎日変更するとか、無意味なイタチごっこしたくないよね。

GPSだと、こういう売り買いはできないよね。
だって、地球上の位置を表すデータでしかないから、地図で建物がどこか、位の意味しか取れないし、屋内じゃ取れないから使えないし。
それがiBeaconだと、設置位置とUUIDの管理で、”レジの前”どころか、”パン屋のレジの前”とか、そんな意味付けされた場所まで紐付けられちゃう。
そして、その位置情報を利用する権利を、売り買いするわけ。むちゃくちゃいいじゃん。

だから、iBeaconのマイクロ不動産市場を作って、不動産鑑定士的な資格認定制度で取引知識の人材確保して、売り買いの場を作って、不法占拠とか、
それに違反する場合はBANしちゃえる、社会の仕組みがでてくるよね。

セカンドライフの土地売買とかあったけど、こっちはすでにリアル世界でリアルに毎日人とお金が動いている場所に意味付けるマイクロな不動産だから、
むちゃくちゃいい値段つきそうじゃない?

位置に紐付けで、あぷりとかパスにトリガーを送る、これだけの仕組みだけど、つまり意味があるからトリガが送られるってことだよね。
しかも、そのトリガーを受け取る権利は、UUIDを知らないと得られない。トリガーを受け取る権利、権利という概念で扱える、これ自体が、ほんとに、ものよね。

なんか、グルーポン的な人たちが、ひゃっはーしそうな話ね。

とか書いてみたけど、当面のiBeaconの使われ方って、私有地、よね。自分のリアル土地に、リアルビーコンを配置して、
閉じた環境で、利用者の動線やら購買記録をゲットして、テナントに月額んー万円で分析データあるんだけどー、みたいな。
それだけでおいしいから、別に第3者にビーコン情報出す必要もないか。

Apple、最強

iBeaconの仕組み自体は、独自に作れますが、ビーコンの電波を、バックグラウンドでiOSが検出してアプリ通知してくれる、これが一般開発者では手が出せないAppleにしかできないこと、だと思います。

ロック画面表示のあのバックグラウンドモード

notify on displayのあの、ロック画面表示タイミングでのビーコンチェックのモード、あれ、やばいよね。

ロック画面の解除で横スワイプの特許があったけど、あれと同じくらい、ヤバイ。だって、ユーザが、なにか欲しいタイミングで、そこでビーコンチェックを入れるのって、むちゃくちゃ自然だし。

常時BGモニタしなくても、自然にチェックできるし。あれは簡単すぎて、でも有効で便利すぎて、ハードウェアの電池減りにも効き目がありすぎて、特許になってたら、やばすぎる。

iAD

iADがiBeacon対応して、お店に応じたクーポンとかリアル場面で有効な広告を出す程度のこと、やってくるだろうし、そのときにどうなるか、どうするかくらいは計画しとかないとね。

フォーマットにUUIDがあるって、つまりそういう意味よね。

スマフォの広告

訓練されたスマフォユーザは画面上部と下部の広告領域を意識外に飛ばせるが、もしもiBeacon連動で、リアルにビーコン領域のその場で使える”オトクすぎるクーポン”、が10回に1回くらいでも配信されたら、逆に広告を見ざるをえない習慣を刷り込める、って程度のこと、常識よね?

このクーポンで目の前にあるお店のなんとかセットが半額、って感じの。それが広告自体に目線を引きつける、撒き餌になるという。

マクドナルドとか、いい道具よ。椅子に加速度センサいれとけば、客入りキャパがわかるから、時間帯予測とあわせて、ちょっとお客を入れておきたいな、って思ったら、そういうクーポンにトリガひっかけたらいいんだから。来店の習慣を刷り込む、ために。iOSのSDKでユーザのIDヒモ付で履歴や好みに合わせて、狙える客を狙えそうだし

ハードウェアってゴミ

BLEの世界は、Appcessory、アプリケーションとアクセサリが不分割な様を表す造語まであるくらい、の世界だけど、iBeaconもビーコン自体がAppcessoryになっている。
ハードウェア単体を販売されても、それを利用するアプリからすぐ使えるSDKに、クラウド側の記録サービス位ないと不便だろうと思う。
でも、クラウド側の保存があっても、動線のデータの保存を他社に任せる、なんてありえないから、クラウドのサービスじゃなくて、サーバのSDK自体を出す形か。

ハードだけで差別化といっても、単純すぎるから、価格競争になるだけろうな。っていうか、めんどくさいから、部品供給元として2~3社残って価格競争してればいいだけだよな。

OSを握られた世界

そもそもiBeacon自体、Appleが自分の利用場面に合わせて適当にいじってくるだろうし、ハードウェアとの統合で、公開もされていない仕様がいつ変更されるかも、わからない。
iOSの更新自体OTAでいつでも更新されるいまどき、ハードウェアとOSの両方を握られた世界で、3rdとしてどうするんだろう。どうもできない。そりゃそうだ。

iBeacon不動産市場

なんかもう、ビーコン無料にしちゃって、不動産市場で、ビーコンの設置位置情報が紐付いた、UUIDやら番号割り当ての一覧を売り買いするところで、
利益出しちゃえばいいんじゃない?ビーコンを置くことで、逆にお金がもらえるくらいの。

スーパーの販促のヨーグルトのビーコンで、競合他社の広告がでるとか、けっこうユカイよね。そういうのはやめての仕組みとか、いろいろ人間の間の調整がいるところって、確実に永遠になくならない仕事になりそうじゃない。

iPhone5以降だと、なぜか、殆ど電池も食わないですし。WiFi/BTのコンボチップに通信制御のマイコンがいるから、そっち側のハードウェア自体に、仕組みを入れてるんかもですね。M7プロセッサ的な。Appleって、ハードウェアは2年前から、iOSの根幹の変化は1年前から、こそっと入れてくるよね。iBeaconにしてもBLE関係にしても。

Passbookがスマートになっちゃう?

一時注目を浴びたPassbookだけど、例えば位置に紐付けして表示されるPassbookって、通勤で毎日利用する駅に紐付けられていたら、
駅につくたび表示されて、とてもうざったい。

外部から処理ルーチン、インテリジェンスが全く入れられなくて、位置=表示、の単純なものすぎて、実用じゃないのね。

でもiBeaconだと、iBeacon->アプリ(処理)->(必要なら)passbookを表示、とかアプリで表示って、処理を間に入れられる。
Passbook自体をiBeaconにひもづけるんじゃなくて、一度アプリでうけて、必要ならアプリからPassbookを出してもいいし、
アプリ自体がPassな画面を出してもいい。

ユーザから見たら、どっちにしても同じようなものに見えるでしょう。

アプリの終焉

いろんな会社が自社の会員カードのアプリを出しているけど、いちいちアプリをインストしたかを思い出すのも、うざったい。
iOS7でフォルダの制約がなくなったから、アプリ全て1つのフォルダに放り込んでいるのよ。だって、使わないアプリばっかりで、アイコンを見るのも、うざいから。

財布にたくさんのクレジットカードがあるような、そんな面倒さ。

でもビーコンがあれば、それに対応したアプリがロック画面にでてくる、というのが作れる。

これって、ユーザが意識してアプリを起動する、の終わりじゃないか?

その店にいたら、その店のアプリを起動したいに決まっているし、レジの前にいたら、支払いしたがってるのに決まっている。それは文脈から、そうだ。
なら、その文脈に合わせたアプリがすでに出ている、というのはとても自然。

Windowsユーザでデスクトップに整理整頓しないファイルが、だばーっと置いてある非効率な人を見て、笑いものにすることもあるけど、iPhoneのアプリも整理整頓する時代、
おわっているのかも。

インストしたことすら忘れる世界、忘れていい世界。必要な時には、ロック画面にでてくる。

ユーザのオプトアウト

UUIDを使ったウザイアプリがでてきても、ユーザは削除してもいいし、タスクスイッチで消せば、アプリには通知が飛ばなくなる。

このオプトアウトって、手軽でいいよね。文句言うほど手間を掛けることもなく、無言で、物理かスイッチャーから、即削除。

M2M

例えば、飲食店の椅子の脚に、圧力でiBeacon的な信号を出すデバイスはめて、WiFi経由でサーバ同期かけたら、”近くで、ご希望の空席があるがあるお店はここ”、って食べログ的なモバイルアプリで表示できるわけで。何百万もの初期費用、なんて冗談みたいなことには、ならずに

NFC

NFCはiBeaconのせいで死んだ事にしたい人が居るようですねー

なんか日本の会社が5カ年計画とか勝手に言って、勝手に自爆したみたいね。iPhoneに載らないから、って子供の言い訳ですか。サーバがないところでも、リーダ/ライタ端末とNFCカード間で、課金のようなデータも扱えるのは、スマートフォンがなかった自体には、便利な仕組みだったし、電車のように短時間に大量の人をさばかないといけない場所では、いい道具だと思う。

でもね、SUICAと一緒に運転免許証を入れたら、TOICA対応の自動販売機で支払い認識しないとか、冗談にも程がある。10年以上かけてJRや私鉄のICカードの全国共通利用が可能になったと思ったら、SUICA内蔵のクレカとバス用の複数枚カードを持っていたら、どのカードが決済に使われたかわからなくなってとか、カードを何枚ももつとか、どっかのカード発行会社は儲かるだろうけど、不便という以前に、スマートフォンがある現在では、頭がオカシイレベルの不自然さ。消えるのが自然な流れというものだろう、それは。

iPod touchでも位置が取れるっていいよね

iBeaconを街の観光に使う。貸出機って、毎月料金がかかるiPhoneは無理で、買うだけですむGPSのないtouchだから、位置取得の欠けてたピース、なのよね。

東京でのお仕事

iBeaconがらみとなると、東京でのお仕事が多そうです。
小売向けに売り込むと、iBeaconとかいう新しいものを特徴付けるのに、人の動線が取れます、とか提案して、もしそれが受け入れられちゃったら、どうするつもりなんでしょう。

Amazonとかウェブの通販ならば、購入履歴やウィッシュリスト、閲覧記録に基づくリコメンドをしても、誰も文句言いません。
だって、購買記録などは、保存するのが自然なデータだし、閲覧記録を解析してレコメンドするのも、最初からああいうものがあったのだから、
いまさら”個人の振る舞いの情報の扱い”に言及する人なんていないでしょう。

でも、リアルだったら?

Androidで、人の行動履歴を他の端末で閲覧できるカレログというアプリを出していた会社は、全方位からの集中砲火をうけて、跡形も無いし、
その後に、同様のサービスを出す会社も、聞いたことがない。
JRも駅の利用記録を第3者に販売するニュースで、匿名性が甘く個人が特定可能ではないか、にまともに正面から答えようとして、販売サービス自体が消えてしまった。
リアル世界の動線取得は、感情と倫理と法律的に、燃え上がりやすくて、怖そう。

これはiBeacon自体には関係がないけど、もしもそれを売り文句にして売れたなら、炎上にむかってまっしぐらになりそう。

あと、そういう売り込みって、売る側と買う側の視点で、そのサービスを利用する人にとっては、何にも嬉しくないものっぽい。なんか、どうでもいい感じがする。

クーポンを配ってもいいけどさー、時と場合を考えなよー

やっぱり買い物場面で、(集客と販売促進で)クーポンを配る、っていう従来活動を、モバイルのiBeaconの新しい器に古い酒どばどばあふれるが如く注ぐ、
ようなことになっちゃうんだろうなって、僕はあきらめ顔を決めるのです。

売り込みに行くなら、そりゃしょうがないんだろうけど、もちょっと新しい要素を入れておこうよー。

例えば、ショッピングモールに数ある商品、数あるお店で、配布できるクーポンは1日1回訪れたら1枚だけ!という縛りルールを入れてみようよ。
販売側は、それで買ってもらえるならで、条件がんばってみようか?それとも、今日は平日のお昼、この人は夕食にワインを飲むみたいだけど、昼だから…そうだ、ワインの美味しいランチのイタリアンの店のワインチケットだしちゃおう、試飲モードで、お高いのを、とか、ちょっとは頑張ってサービスしてみるきにならない?1枚だけって縛りを入れたら。

売り込み側も、ただクーポンを無能に垂れ流して手数料ゲットとか、頭の悪いことできなくなるから、がんばるよね。
さっきのワインうんぬん的なデータ提供とか分析とか、一生懸命頑張るよね。

クーポンを受け取る側も、…そうきたか…くやしいが、使わざるをえまい、とか、なんかみょーにサムライっぽく神妙に画面を見ちゃうよね、1枚だけルールって知っていたら。

不自由だけど、不自由ルールで、SMやる気はないけど、ちょっと頑張ろうよ。古い酒を、だばーと垂れ流しててすうりょうげっとー、
マスな顧客げっとー、集客オッケー、で誰もなにも買わない賑やかな売上激減のゴーストタウンを作りそうな、ひゃっはーやめようよ。

新しい器には、すこしは新しい酒を用意しましょうよ。

開発費用とか

“iBeacon専用の顧客動線解析システムです” (1億円です)とか、札束を抜き出すテクニックあるヒトってどんだけいるんでしょうね。

O2Oとかいって、オフラインとオンラインの垣根がなくなるっていう意味は、ウェブのコマースなノウハウや蓄積が、そのままリアル世界に使えるってことだから、そんな、新規開発、しちゃうような頭のオカシイ開発元とは、最初っから関わったらだめだろう、なんて思っちゃうけど。

例えば、店内にヒトが何人いるか。ビーコンにURLを対応させておいて、アプリがBGでenter/exitのタイミングで、Google Analyticsにパケットを1つ流す仕組みがあれば、あとは、ウェブの通販サイトやらの資源が、そのままつかえるでしょ。
無償の範囲でも、Google Analyticsでリアルタイムに何人アクセスしてるかがわかるじゃない。お店にURL紐付いてたら、それって店内にいる人の数じゃない。
ちょー大手なら、何十億円規模の投資で自社内に人込みでリソースもってるだろうし。

新規システム開発、危険よね。そういうシステムって、ソフトウェアだけど、扱いは投資しつづけて陳腐化させない結構たかつくうえに、それだけで会社が1つ作れそうな、
ハードウェアっぽいなにかよね。共通部品よね。
そんなの、まだトライするまえ、投資価値もよくわからないときに、目新しさで、どーんと開発費とか、言う方も聞く方も、頭おかしいよ。

ビジネスなモデル

打ち合わせログをみてて、iBeaconとかが好例だけど、基本ハードとライブラリで金を取るって無理。サービス実施、コンサルとか、より上位と組み合わせて課金がいい。だってAppleのものでしょ?的な。そうなると、アニメの製作委員会みたいに、会社が集まって製作、利益分配って形

でね、iBeacon関連で盛り上がる話をするとき、なんで”今ブログでみた単発ネタ”に目がいくのよ。事業でしょ?ロードマップ作って、5年後まで、技術要素とインフラ整備で列挙して、自社方針のロードマップを作れよ、とか、アホらしくて、素でツッコむレベル

あと競争ってのは、相手の意図ではなく相手の戦力をもって意思判断するべしなので。iBeacon関連でAppleの意図、動向予測は〜、とか、根本から頭が悪い。じゃなくてAppleが持っている戦力からうてる手段を列挙、対応手段を列挙、致命になるポイントの把握、なの。”予測”?あほか

セミナーで、”私アプリの勉強会って嫌いなんですよ。iBeaconってアプリxハードのサービスだから、ハードの簡単な工夫で解決する課題を、アプリだけで解決しようとするとか、頭悪い以前に視野狭窄にもほどがあるけど、勉強会って狭窄だから”とか、ぶっちゃけてました

iBeaconとかいってるけど、こんな室内位置の分野は20年昔からあるから特許に規格に技術にと、時間と資本を投資しててすでに札束での殴り合い勝負の世界なのに、iOSが出たからプラットフォームが整ったタイミングを見て、いまごろ世界を取るぜとか、頭おかしんじゃない?

iBeaconの案件って、どっかてに提案、の形をとった瞬間、ストーキングできるぜバンザイ、になるよな。もしもサービス提供者が、確たる信念を持って考えるなら、利用者のためなものにできるかもしれないけど。売り物として売り込むと

iBeacon関連の勉強会、アプリ側の人間しかいない場って、バカじゃないかって思ってたりする。こんなサービスにしたい、っていうのが、電波の放射パターンと設置位置に直結するから、欠けた視点で話して、どうすんだろう

iBeaconからみで売り込むなら、クーポンがーとかO2Oがーとか、それっぽいかっちょいいこと言わずに、客を個別にストーキングできます、って素直に言えばいいのに

モジュール販売だけのプランで利益がでるわけがないじゃないw だって2ヶ月後には、ああなっちゃうんだよ、とか動向と情報を掴んで、アプリのSDKとサービスの更新準備できないと、”iBeaconの変更に伴い3ヶ月停止します”とかになっちゃうんだよwww

iBeaconのハードウェアやりますというので、ちょっと聞いた感じ、ビジネスモデル作ってないんだろうな、って思った。来客頻度やら経路追跡の簡単な運用マニュアルとサンプルアプリなしにハード売れるのかしら

Androidがー

iBeaconな打ち合わせログを見てて思うのは、”Androidnについて聞いてくるところとは、関わるな”のルール。
そんなことを聞いてくるのは、iOSでシェアが取れないと思っているからなんじゃないかな。スマフォの6割がiPhone、そこで上位3〜5位のシェアが取れないなら、先はないと思う。
いくつか見たけど、本音なところ、先はないと思う。

なぜか、Androidが、っていうところは、きまって”お客さんの要望で”っていうのが、ついてくる。
自分のとこのSDKに絶対の自信をもってiOS専用で押し切ればいいのに。
どうせ、今年のAndroidで対応したら、努力した結果、”つかえないよねー”って印象植え付けておしまいなのに

AndroidでiBeaconが-

いろいろ技術的な説明をするのもめんどくさいんだけど、今年はやめとけw、なの。

開発元を選ぶ時

iBeaconとか、新しい話題でちょっと開発元を選ぶ時、ぶっちゃけ技術や人を見て発注先を選ぶ、って不可能だと思う。
ハードウェアとかソフトがからむは、Appleの意向で四半期ごとにガランと変化する可能性があるわ、開発だけなら見た目動いているものは、
どこでも作れるわ(サンプルが転がってるので)、そこで見分けるのは不可能。

ただ、簡単に見分ける方法が1つあって、”決済、O2O”とか、そんな単語を混ぜてくるところは、ちょっとその技術内容を聞いた方がいい。
iBeaconって、”位置と近接の検出技術”であって、決済とかO2Oとかは、その上の使いかただけの話なの。
だから、決済がー、で売り込んでくるところと一度関わると、お客さん、いいんですかー、決済システムを総入れ替えで、業務がんー日とまりますよー、みたいなことにも、ないとはいえない。

ま、そんな、ずぶずぶな関係が好きなら、べつにいいんだけど。決済を変なとこに握られるって、商売人として、死んだも同然よね。

チートし放題

BLEのアドバタイズなんて、スニフし放題、コピーし放題。それを技術でカバーしても、悪意の薄いただのバカ避けにはいいけど、ほんとに悪意がある人には通じない。

運営とかで、カバーしてください。あと、最初に計画にいれていなかった穴ふさぎを、あとで技術側にすべておっかぶせるとか、そんなことしても、やりようないうえに、本来生じないトラブルの原因を自分で仕込むようなことにしかならないから、さっさと最初の計画からやり直してください。
ってか、最初の計画立案から、技術者入れといてください。

自然なものならいいのかも

リアル世界でも、購買記録は保存しないとだめだろうし、クーポン発行したら、その記録はサーバに置いておくのが普通だろう。
そういうユーザからみて、そう処理するのが自然、そう処理するしかない、場面で取れるデータなら、炎上せずに利用もできそう。第3者に販売、なんてことしちゃだめだろうけど。

カスタムなビーコンの開発

Estimoteの加速度とか温度で新しいことが〜、とか言っちゃうなら、SensorTagのファームちょっといじって、今すぐ実験すればいいじゃない。

ハードウェアはわからない?やってみたら、サンプルをコピペで終わる、簡単な作業よ。

レジの待ち時間が

もしもレジに並んである間しかプレイできないゲーム、とかあって、それがむっちゃ面白かったら、買う予定がないのに人が並んじゃったりしてね。
iBeaconならできること。
ビーコンのオンオフは自在にしといて、レジにでも機能で組み込んじゃって、列が長いなーってときだけ、レジが気を利かして、ゲームモードONにするとか。

おでんを買うたびに、付随する武器や防具がゲットできるドラクエとか、いやすぎる

iBeacon絡みで、決済までスマフォでできるなら、おでんを買うと、それに紐付いた武器や防具がゲットできるRPGとか。
いやだよな、ちくわぶ、に伝説の剣がヒモ付られてて、関西だから買えないとか、そういうの。

スーパの販促にビーコンがついたりしたら

スーパ自体もビーコンをだすだろうけど、販促で例えばヨーグルトの説明動画を流しているガジェット、あれにビーコンを入れておいたら、
アプリ連携で、その動画サイトにジャンプとか、なんかパズドラ的ななにかのスペシャルコラボなんとかがゲットとか、ありよね。

勝手にビーコンを置いてもいいじゃない、っていうルールづくりは、ビーコン製造販売会社が群れになって、ルール運営してほしいところね。

ゲームイベントくらいの会社間連携してほしいよね

iBeaconって、物理的にビーコンをごっつん叩いた瞬間にビーコンの電波を出すとか、そういうのも作れるじゃない。
だから、リアルなショッピングモールのイベントとかで、ドラクエっぽい宝箱を置いておいて、叩いたらコインとか電子なアイテムげっとーくらいの、
ゲームイベントはしてほしいよね。すでに設置したビーコン情報を供給してくれたら、そういうイベントに、準備ゼロでソフトだけで対応できそうだし、コスト小さそうだし。

O2Oとかいうなら、ゲームとか、むっさオンラインやん、そっちオンラインやん、って世界もついでに、オフラインに引っ張ってくるくらいの、会社連携ほしいよね。

Androidも対応?

iOSだけでいいと思う。iBeaconを使ったものは。
iBeaconみたいなのは、この6年位でベンチャーも出てて、WiFiでAndroid向けにiBeaconと同じことができるサービスを提供している会社もあるみたいだし、
Android向けにはそれを利用すればいいと思う。

べつにiBeaconだけで全て解決しろ、なんて誰も要求していなくて、こんなことやりたいんけど、がちゃんとできたらいいだけだろうし。

ポイントとかアプリとか、うざいんよ

ポイントはほしいし、なんか電子なキャラとか欲しいから、アプリ入れたりするけど、基本、画面みてアプリを起動して、なんか店員さんと同期してiPhoneをふりふりシェイクしてひゃっはー、とか、恥ずかしいんよ。むっさ、恥ずかしいんよ。リアルでやらせないでよ。あと、操作するのも、めんどい。

オンラインの客をオンラインにひっぱりだすんでしょ。こっちは、引きこもってるの。なんで、リアル人と、ひゃっはーインタラクションせにゃならんのよ。恥ずかしいんよ。

iBeaconはバックグラウンドで動くんだし、ロック画面表示したら自動で、その場面にふさわしいパスなりアプリ通知なりがだせるんだから、よろしく後ろで処理してよ、ホントお願い。操作とか、アプリを選ぶとか、うざったいこといるなら、…100円くらいの価値があったら、するかも…50円だとしない…ごめん、みみちくて。

足首にゴムの跡が残らない靴下がほしいだけなんですけど

ショピングのiBeacon利用で、売り場に近づいたら割引クーポンが、みたいな買え買えシーンがでてくるけど、あほなの? そんなうざったい売り場、誰が行くの?って思う。

3足1000円の靴下を買ったら、ゴムがきつすぎて、脚に跡が残って、安物買いの銭失いだと泣きながら新品のものを捨てた。でもゴムの張力なんて、長さと弾性係数が分かっていたら、簡単に計算できるし、自分の好む張力なんて1回計測しておけばそれでいいだけ。

ならば、靴下の売り場の前に立った瞬間、私の好みの張力の商品だけ、表示するくらいのこと、簡単にできるはず。iBeacon使って、その程度のサービス、して当然だし、そんなサービスもなしに、3足1000円だ安いだろう買え、なんて店、とっとと消えろって思ってる。

あるいは、サンプルの靴下が気に入ったら、アプリでぽっちっとすれば、自分サイズに製造されたのが宅配されるとか。その程度、普通にあっても、当たり前よね。

ビジネスのシャツのサイズも、首周りと肩幅の組み合わせだけなのに、むっちゃくちゃたくさん種類あるよね。あんなの試着用のを1つだけ置いておいて、生地とか風合いだけ確認したら、ぽっちっとiPhoneのボタンを押したら、自分サイズのそのシャツが自宅に通販で届く、くらいのこと、あって当然だよな。いやじゃない、わざわざシャツを受け取って持って帰るの。

あと、靴のサイズ。専門店とか言ってても、満足するほどフィットしたものを薦めてくれた試しがない。結局自分でフィットさせて、4足くらい買って、これかなっていう1つを見つけるとか、とんでもないバカなことをしている。どうにかならない?

魔法の杖

毎度毎度だけど、新しい技術が出るたび、自分の頭のなかだけの想像で勝手に盛り上がってひゃっはーするオカシイ人がいるけど、iBeaconも、思った通りのことができる、いままでなかった魔法の杖”を勝手に想像しないで、目の前にある新しい道具を、道具なりに使ってあればいいだけ、って気づこうよ。

物理なこと、ちゃんと調べようね

iBeaconでTL検索を見てると、電池の持ちやバックグラウンドで誤解しているTWがあるけど、もう講演とハッカソンと地味な打ち合わせで、伝えるべき人たちには誤解なく伝え終わったと思うから、いまごろ話題にするようなのに関わるめんどくさい仕事をしなくてもいいよな、と思った

スタンプラリー

iBeaconネタは、例えばコンビニの来店チェックの商用利用目的で設置されてても、UUIDとか分かれば、例えばゲームやスタンプラリーのようなイベントに使えるタグなのが、おもしろいね。GPSでもできたはずだけど、これは確実に検出可能で位置が局所だから

ドライブスルーならぬウォークスルーとか

iBeaconは設置のしかたで、エリア定義ができるから、お客さんが店に何十秒後に到着するか、わかっちゃったりするシステムもありよね。ハンバーガーをぽちっとして、歩いて行って(1分くらい?のところで、アプリがBGで通知を飛ばして)、作りたてをすぐ受け取って、ウォークスルー。

移動のデッドタイムを利用して、レジでおまたせしません、快適でしょ、みたいな売り方にみせかけて、実はレジ作業の効率化が目的とか、そんな感じになりそうだけど。

電話注文のお客さんが受け取りに来なかったらどうするのだろう?、捨てるしかないじゃない、って思うけど、考えてみれば、回転すしって廃棄率がものすごいのよね。計画に盛りこんであれば、回るんでしょうね。

オープン仕様?

iBeacon的なものって、出だしだから、JRの駅のデータの第3者提供みたいな感じでケチがつくと、とてもいやんなので、技術内容についてはオープン無償で話するように、切り替えましたの… (可能/不可能程度の雑談は。高度なのは有償にしてますが)

アホなの?

iBeaconのRegion検知は、Regionから出てく時が遅くてムズムズするね。っていうけど、ならリージョンを重ねて、出た/入ったを組み合わせる配置設計くらい、考えるよね?考えるよね?

ポイントってなによ?

近所のケーキ屋さん、毎週行くけど、2つ入る箱に入れてくれるから、運搬時の重量バランスと見栄で、独身なのに毎回2つ買うんですよ。350円x2=700円。太るよ、むっさお腹の脂肪がたっぷたっぷだよ。それはいいとして、月に4x700円x12=3万円くらい。うわ、めっさお金使ってる、って驚くけど、毎回ポイントカードを持っていくのを忘れるから、そのポイントを受け取ってないのよね。

毎週行く店でも、毎日ポイントカード持ち歩くのって、おさいふを太くするから、いやじゃない。そのかわり、お腹が太くなってるけど、そっちはそっとしておいて。

で、スマフォでカードが一括とか、iBeaconでO2Oとか、いいんだけどさ、そういう先進的なことするまえにね、
いや、カードが仮想になるだけでも、手ぶら間がまして、いいんだけどさ、会社がそれぞれ別で、お店ごとに別系統の会社使ってたら、結局ポイントが分散して貯まんないじゃん。

いやiPhoneに全てが収まるから物理的なカードは1つに集約されてて、いいんだけどさ。ってか、ユーザの顔と名前がわかってたら、iPhoneいらなくない?お店からポイント発行したら、べつにiPhone持ってなくてもいいよね。って、そういう顔なじみなところは、置いておくとしてもさ。

業界で協会でも作って、共通ポイント化してよ。どこのポイント付与会社からでも、共通ポイント出だしてくれたら、むっさ貯まるよ。お腹のお肉と比例して、ポイント貯まるよ。もう、お願いします。

ってか、ポイント発行のモバイルサービスを展開するなら、ついでに決済サービスをとれよ。むっさO2Oの手数料やん、ってかポイント発行っておまけじゃん。決済というかレジシステムごと、あるいは税務とかの帳簿システムの会社と連携して、ごっそり取ってこいよ。おんなじ営業するなら、まとめて提供してこいよ。なんでそんな、ピンポイントで攻めるんよ。導入側も、ちまちま、めんどくさいじゃん。

そもそも論として

O2Oとか集客はいいとして、出てくる手段が、(割引)クーポンとかって、いつも行く馴染みの店で、割引クーポンもらって嬉しいの? いや、顔なじみだとわかるほどの客だったら、クーポンなんぞ見せなくても、店員さんがデフォで割り引くくらいのことするでしょ。ってか、なじみの特典が割引?そんなの、どっちも、うれしいの? ちょっと笑顔が素敵になる(小首を10度傾けるスペシャル笑顔にグレードアップ)、くらいでいいんじゃないの?

店員さんが毎回変わるから覚えられないので、っていうなら、iBeaconの仕組みを利用して”プレミアムな顧客検出”くらい、そっちでやって、かってに割り引こうよ。
できるから、がんばらなくても、けっこう簡単に仕組みが作れるから。やろうよ、そっち方向で、がんばろうよ。昔は、そういう道具がなかったから、そうやってただけだから。
新しい道具は、それなりに使おうよ。

お客にクーポンを表示させるような、あんた一見さん?、てきな恥ずかしい行動させるの、やめようよ…

ところで、真顔に戻って聞くけど、安く売るしか能がないの?

なんで見たままで、本質を理解したり想像したりしないかな?

iBeaconってBLEのアドバタイズだから、ファーム次第で、どんなデータにも変更させられるし、BLE自体の機能で独自のブロードキャストしてもいいよね。
もともと位置の検出技術だってAppleもいってるじゃないの。なんでO2Oとか決済とか、視野狭すぎの、想像力なさすぎの単語雲泥で考えるの。

もっとでっかい遊び方と利益があるでしょ。

BLEって送信機が安いから、ビーコンでアプリを叩いて起こして、それで詳細情報はBLEで別口で取るとか、それくらいの仕組みは簡単にできるし、
アンテナを工夫したりして、電波受信範囲を10cm から 多数の同じIDのビーコンを面配置して1kmをカバーとか、できるし。
やれよって思うけど。ハードに手が出ないじゃなくて、そういうことやりたいから、ハードやる人見つけてお金だしたら、できるやん。

変なところで、iBeaconみたいなできること、で小さくしぼむなよ。あほすぎる。

不動産ってことは

リアルに空間を所有しているところが、ビーコンを設置したら、それに意味付けで新しい不動産資産ゲットな感じで、よさそうね。
巨大ショッピングモール的なものとか、公官庁の図書館とか、ドラッグストアとか、空間を無駄に持て余してそうなところに、新しい切り口の価値を与える、
って表現すると、ちょっとかっこいいじゃない。

もしもリアルに空間を持っていなくても、全国のパン屋さん連合が、揃ってレジ前にビーコンを置けば、それだけで協会から、
その権利を販売します的なこともできそう。人の集まりって、強いよね。

テリトリー争いになるかしら

ならないんじゃない? iBeaconの電波自体は相互干渉しないし(30m範囲内の100個とか極端な場合でもなければ)。設置許可をもらってもいないのに、
勝手に設置した場合は、その空間の所有者は排除したくなるだろうけれども、違う意味付けなら同じ空間に多重にビーコンを配置してもいいよね。

スーパーなら、そのスーパーのお店の配置を知らせるビーコンで、レジ前とか野菜売り場とか、そんなのをスーパー自身が置くだろうし、
ちょっと今週は焼き鳥の販促イベントだからで、外部の焼き鳥屋さんがビーコンを置いて、焼き鳥カードげっとだぜアプリみたいなので集客しても、
それはそれで、それぞれがUUIDを管理運営すればいいだけだから、いいよね。

店の前で、いらっしゃい的な呼び込みを、リアル肉声でやってるじゃない。
ビーコンといっても、結局それと同じようなものだから、客引きしたら殴られる、状況じゃないなら、今までどおりの仕組みの中で、肉声が電波になりました、
ってだけで運営できそうね。

肉声と電波の違いって、クラウドにつながるか否かだけね

じゃ、なんで肉声はテリトリーにならないか? それはiPhoneがないから。電子データを配布しても、それを受け取って保存していくには、iPhoneがいる。
なにか紐付けて広告配信でも、やっぱり受け取るのはクラウドにつながったデバイス、いまならiPhone。
そのうちウェアラブルなもので、直接受け取るかもしれないけど、それはデバイスが変更になるだけだから、本質どーでもいいこと。

あと、iPhoneって、個人データを満載しちゃってもOKなデバイスなのが、大きい。同意なく、あるいはわかりにくい規約で同意をとって、
もしも性別と年齢をサーバに送信してましたとかバレたら、全方位からフルボッコされそうじゃない。
でも、iPhoneのアプリで閉じてるなら、そういう殴られる理由を踏まなくても、その人にあったなにか推奨するロジックをアプリ側で走らせて、いろいろできそうだし。

で、ビーコンってUUIDで、知りたいものだけわっちするけど、音声の肉声って、聞きたいかどうかを指定できないから、iBeacon最高って感じがする。
できればSiriの声がミクになってて、ビーコンのUUIDでヒモ付コンテンツをSiriが語りかけてくれたら、オフラインにちょっと行こうって気にも…いや、びみょう、しょうじき、さすがにどんびきだわ。

iOSって、変わるよね

iOS7.1、iPhone4sでのiBeaconのテスト、やったほうがいい…

最後に

司令官、私がいるじゃない!

12月17日 大垣 iBeaconハッカソン

iBeaconハッカソンとは

2013年12月17日に、岐阜県大垣市 ドリーム・コア2Fメッセで、パブリックな建物を使った、おそらく世界でも初のハッカソンが開催されました イベントページ: https://www.facebook.com/events/772613819421404/。ハッカソンは、”ハック”と”マラソン”を組み合わせた造語で、開発者やデザイナが集まり集中的に共同作業をするイベントを表す言葉です。

iBeaconは、Apple社がiOS7で導入した位置と近接検出技術です。このiBeaconを利用した製品開発やサービス提案には、ビーコンと呼ばれる電波を発信するハードウェアや、ビーコンの信号にあわせたユーザ体験の設計など、ソフトウェアだけで開発が完結していたアプリケーション開発とはまた異なるスキルが必要になります。大きな期待が寄せられているO2Oや決済といった単語とからめて、記事に取り上げられるiBeaconですが、実際に実物のビーコンのハードウェアを手にして、その振る舞いを体験した人は、まだ極少数です。

iBeaconがどのようなものかは、実際に手に取り、体験してみればよくわかります。そこで、iBeaconの課題や可能性、そして面白さを、参加者間で共有するアイディア・ハッカソンが企画されました。ハッカソンは、岐阜県大垣市にある情報産業の拠点、ソフトピアジャパンにあるインキュベート施設ドリームコアの建物1つをまるごと使いました。建物のあちこちに計30個のビーコンを参加者に配置してもらい、それをアイディアを実施した場面と見立て、実際に振る舞いを確かめ理解を深める体験を、共有しました。

ビーコンは、(株)アプリックスから提供を受けました 中日新聞および岐阜新聞で日本初の「iBeaconハッカソン」に関する記事が報道 http://www.aplix.co.jp/?p=7891

ハッカソンには、東京からの日帰り参加が難しい大垣という場所で、しかも年末という時期にもかかわらず、30名弱が集まりました。北は北海道、西は石川県、東はカリフォルニア、南は兵庫県と広い地域から参加者が集まりました。そのスキルや背景知識も、半導体回路設計、ハードウェア開発者、無線技術者、iOSアプリケーション開発者、ウェブ開発者、それに経営者にバリスタと、ユニークで多彩な集まりとなりました。

プログラム

ハッカソンのプログラムは、以下のとおりです。午前中にiBeaconの基礎知識などのイントロダクションを行い、お昼ごはんを食べながら自己紹介をしました。午後からは、実際にビーコンを手にして、iOS SDKの振る舞いや、電波の信号強度の変化を、遊びながら、実体験しました。その後、チームに分かれて、アイディアスケッチとディスカッションをおこないました。

  • 11:00〜12:00:イントロダクション
  • 12:00〜13:00:昼食 (お弁当を食べつつ、自己紹介)
  • 13:00〜13:30:ビーコンで遊ぶ
  • 13:30〜15:30:チームごとにアイデアだし
    • アイデアスケッチ#1(アイデアスケッチ:20分+共有:10分)
    • アイデアスケッチ#2(アイデアスケッチ:20分+共有:10分)
    • 投票とディスカッション(20分)
  • 15:30〜16:00:チーム間で共有(兼休憩)
  • 16:00〜17:30:ビーコンを実際に設置してチーム内で実験
  • 17:30〜18:30:チームごとに発表
  • 18:30〜19:30:全体でディスカッション
  • 発表

イントロダクション

イントロダクションのプレゼンテーション資料です。

アイデアスケッチ

アイディアスケッチの手順を説明するプレゼンテーション資料です。

チームのプレゼンテーション

5チームが、それぞれのアイディアと実験結果をプレゼンテーションしました。

最初のチームは、車の盗難に備えたビーコンを発表しました。
クルマが盗まれると、ビーコン信号が出ます。盗まれたクルマを特定できるUUIDなどの情報をネットに登録しておけば、だれかのiPhoneがそのビーコンを検出した時に、通知される仕組みです。
発信器を、クルマのダッシュボードや助手席に置いて、車内から車外に電波が出るかを実験をされていました。
朝起きたら駐車場にあるべき自分の車がない、クルマを盗まれた実体験をもとにしたプレゼンテーションで、迫力がありました。

iPhoneの置き忘れ防止のキーホルダー(keyfob)は、Bluetooth Low Energyが利用される、よくある商品群です。
しかし、それは自分のiPhoneとだけ接続するもので、自分のiPhoneからしか、使えないものです。
不特定多数にID情報を発信し続けるビーコンの特性と、バックグラウンド状態でビーコンを検出できるiPhoneの機能、そしてそれをソーシャルの要素と掛けあわせて、自分では探せないものが探せるようになるところに、大きな可能性があります。

2つめのチームは、決済などのサービスです。今まさに提案している案件が、実際のiBeaconに触れてみると不都合があることがわかり、もしもこれを知らずに開発をはじめていたとしたら、ぞっとすると話されていたのが、印象に残りました。

3つ目のチームは、街路にビーコンを設置しておいて、自動車のフロントウィンドウにビーコンに紐付けられた情報をAR表示する、というものです。
クルマが早く移動しすぎると、iOSがビーコンを検出する前にビーコンの到達範囲を行き過ぎるかもしれません。ドリームコア前の街路にビーコンを設置して、そこでクルマを時速20km/50kmで走らせて、振る舞いを実験されていました。ビーコンの信号モニタアプリの画面を動画撮影して、記録に残していました。

4つ目のチームは、クルマの運転中に心臓が停止した状況を想定しました。実際の車を使ったデモンストレーションでは、心臓が停止したらビーコンを送信するウェアラブル機器を、ビーコンの電池を手で出し入れして模擬しました。受信側のiPhoneに、イヤホン端子にLEDを接続して、受信信号強度でそのLEDの光り方を変化させる機能を実際に製作されていました。車自体に、ビーコンを検出したら路肩に移動する機能を入れることもありうる、と言われていました。あの短時間で、まさか実際のアプリまで作るチームが出てくるとは、予想外でした。

5つ目のチームは、新人教師が地元のおばあちゃんを訪問する場面を想定されました。表の目的は、おばあちゃんに挨拶をすることですが、裏の目的としておばあちゃんの安否確認を仕込まれている、細かい設定です。デモンストレーションでは、建物の4箇所にビーコンとおばあちゃんの似顔絵を設置して、それぞれのあばあちゃんを訪問しました。そのデモンストレーション・アプリは、訪問時の情報をネットワークを通じてウェブ側に投げていました。その滞在時間をヒートマップ表示するウェブアプリまで作られていました。今回は、実装までする時間はとてもないと思っていましたが、超速でここまで作られていて、さすがというか、驚きました。
動線検出は、従来の手段では実現ができなかった、iBeaconという新しいものを売り込む強力な謳い文句になるのでしょうが、まさに、それを実証するデモンストレーションでした。

写真

30個もビーコンが集まると、丼に入れて持ち運びたくなります。冬場なので、回路が静電気で破壊されないように、モジュール1つ1つを、静電防止ビニールで包みました。

iBeaconを使う美濃市の観光アプリの、デモンストレーション場面です。iOSデバイスを持っていない方に貸し出す機器は、iPhoneでは毎月回線料金がかかるため、ハードウェアの購入金額だけですむiPod touchやiPadになります。しかしそれらにはGPSが搭載されていませんから、観光地案内に必ず欲しい地図表示に適しません。iBeaconを取り込むことで、位置が検出できるようになり、これを解決できるわけです。

今回使用したビーコンの発信器は、アンテナに基板実装されたチップアンテナを使っています。
この写真は、丼をアルミ箔で覆い、パラボラアンテナのようにできるかな、と試しているところです。また、丼の底に波長よりも小さい穴を開けて、その穴から漏れ出る近接場の成分で、NFCのようなタッチが再現できるかもしれません。電波を出すものは、アンテナの種類や、アンテナの周りに反射板を設置して、電波の放射パターンをいじるのも、ユーザ体験を作り出す手段として、おもしろいのです。

ガラスの壁に貼り付けたビーコンです。壁や部屋の材質が、鉄筋コンクリートだったり、鉄だったりすると、また振る舞いが異なるのでしょうか。

振り返って

FacebookのBluetooth Low Energyの公開グループで募集したこともあってか、iBeaconに強い興味関心をすでに持たれている、スキルのある方たちが集まっていました。

雑談

美濃市でiBeaconを利用した観光アプリを出されている、トリガーデバイスの佐藤さんの体験談は、聞いていて、なるほどと思い、またそうなるかと爆笑もする、楽しい話でした。
例えば、電波の発信器の設置作業は、人から見えない場所を探して、手のひらサイズの電気回路を取り付けます。これが、はたから見ていると、爆弾魔が爆弾を設置しているのと見分けがつかない、というのは、たしかにそうなのでしょうが、笑ってしまいました。

実際にやってみると出てくる、あとになって考えたら当たり前なのかもしれませんが、いろいろな出来事や工夫が、参考になりました。

距離の推定、電波の振る舞い

iBeaconを実際に使ってみると、思っていたのと違う、という声が上がっていました。
距離が取得できる、と聞いていたが、その距離がどの程度の精度で取れるのか、そしてImmediate/Near/Farの実際の値が、想像とは大きく違ったようです。

ビーコンにくっつけるほど近づけないとImmediateの反応にならず、私も50cmくらいでImmediateになるのだろうと思い込んでいたので、驚きました。
またレジにビーコンを設置してた場面を想定して、手にiPhoneを持った状態で、レジの方を向いて、次に背後(ビーコンが背面)を向くと、受信信号強度がぐっと小さくなる、という体験もありました。電子レンジにも使う2.4GHzの電波は、水で大きく減衰しますから、人体で減衰したのでしょう。

実験に使ったドリームコアには、1Fと2Fに大きな吹き抜けがあり、また外壁がガラスです。ですから、通常のビジネスビルとは異なり、ショッピングモールを模擬することも可能だったでしょう。

2Fにビーコンを設置した場合、2Fのビーコンが見通せるならば1Fでもビーコンを受信できるが、影になった途端に受信ができなくなったという体験もありました。
2.4GHzは直進性が高いため、見通し範囲とそうではない領域で受信信号強度が大きく変化します。
携帯電話でも2GHz帯を利用する基地局の配置には、周囲の環境が複雑に絡み合うために、実測をして細かい調整をします。
iBeaconでも同じように、壁や建物による減衰や回折、そして反射波によるフェーディングが生じます。

実は、2.4GHz帯の電波発信装置を利用した動態把握は、古くからある研究/実験テーマです。検索すると、総務省の人の動態把握等のためのユビキタスネットワークに関する調査検討会 が出てきたりします。もともとGPSのように、位置を検出する技術としては開発されていないものを、電波の受信強度だけで、位置推定に流用しようとすると、技術だけでは解決が難しいことが、いくつも生じます。技術だけではなく、運用や利用方法の工夫を組み合わせること、また計画当初から、iBeaconは全てを解決する魔法の杖ではないと理解して、その特徴を押さえた利用場面に落としこむこと、が重要だと思います。

Passbook的な使いかた

Passbookを日本で最も最初に実運用した方が懇親会で言われていたのが、”例えば駅で表示するPassbookがあったとする。毎日の通勤で駅に来るたびPassbookが表示されて、非常にうざったい。”という、Passbookの致命的な振る舞いを指摘されていました。iBeaconはPassbookと連携します。ですから店頭にiBeaconを設置すれば、そこを通るたびにクーポンを表示させたりできるわけです。ですが、その振る舞いはGPSのものと同じですから、やはりうざったいものになるでしょう。

Passbookは位置に入ったことをトリガーにして表示させる機能がありますが、実際に位置に関連づけたコンテンツをユーザに表示する利用場面では、その表示が適切か、を判断するロジックを入れることが、必要になるのでしょう。iBeaconでアプリケーションを反応させて、アプリ自体でクーポンを表示させるとか、あるいはアプリからPassbookにクーポンを発行させるなら、そのロジックをアプリ側に入れることができるわけです。

とてもインテリジェントな、Passbook的な何か、あるいはPassbookができるわけです。

ショッピング以外の用途

iBeaconの一般向け紹介では、販売店での商品紹介や支払いでの利用が紹介されていますが、そのようなショッピング以外の用途にも大きな広がりが期待できます。iBeaconの信号は、バックグラウンドで常時モニタできること、そしてiPhone5以降の機種であれば、ほとんど電力を消費しない特徴が、これまでにない利用場面を可能にします。

ちょっとしたハードウェアとアプリ開発者

ハッカソンの後にあった懇親会では、バスの人検出装置が出力するパルスをAndroid端末で計測して、データをクラウドに上げるものを作りたいのだが、ハードウェアが出来る人がいない、という話をされていました。ハードウェア技術者の視点からは、あまりに単純すぎて、お金をもらうことも難しそうなものですが、スキルがなければ実現ができないものではあります。ちょうどその場に、そのようなハードウェアを作れる方がいたので、お話をされていたようです。

ハードウェア - スマートフォン - ウェブ・サービスは、これまでいくつもの案件があり、そしてほとんどが失敗に終わってきました。iBeaconもそうですが、特に従来になかった新しいものを開発する場面では、関係者全員が、全体を俯瞰した視点を持ち、それぞれのスキルを持ち寄り、利用シーンを想像して、協業することが、成功には欠かせません。しかし、ハードウェアに関しては、スキルがある人はいても、会社に囲われてしまい、自分から外にでる人が(東京ですら)いないようです。

遊びを通して

iBeaconは、ハードウェア - スマートフォン - ウェブ・サービスの要素ごとに工夫出来る余地があります。それらを掛け算していけば、利用範囲は無数に広がります。それには、しっかりとした知識と、分析、そして分野ごとの切り分けが、共有できていて、メンバーそれぞれの専門スキルが掛け算されることが重要です。

ハッカソンでの、体験と遊びを通して、試すこと、分析すること、理解すること、結果を話すこと、そして共有することをやりきった先にあった、背景知識や分野が異なるメンバーがチームとなり全体を俯瞰しつつ、結果を出されていた今回の動きは、iBeaconを手段として、自分たちの手で作り上げる、スマートフォンのあるちょっと未来の魅力ある一場面を生み出す、何かに通じると感じました。

謝辞

会場の手配またハッカソンの企画および運営は、IAMAS 准教授 小林 茂さん、そしてトリガーデバイス佐藤さんの尽力によるものです。トリガーデバイスは 近づくだけで美濃観光案内 近距離通信規格を用いスマホに のビーコン設置とアプリケーション開発も担当されています。今回のハッカソンでビーコンの振る舞いを確認するアプリケーションも提供を頂きました。
このような時間と場を設けていただいたお二人に、また岐阜県の担当者の方々に、重ねて感謝いたします。

Apple Notification Center Serviceの解説

Apple Notification Center Service とは

Appleは、Bluetooth LEにいち早く対応し、またその利用領域を毎年拡大しています。

2011年に世界で初めてBluetooth Low Energyに対応したiPhone4sと同時に公開されたiOS5は、CoreBluetoothフレームワークで一般アプリ開発者に、Bluetooth LE周辺機器との接続を開放しました。翌年のiOS6は、セントラル・ロールに加えて、ペリフェラル・ロールが追加されました。

iOS5とiOS6は、個別のアプリケーションとBluetooth LE機器との接続だけでしたが、iOS7からは、iOS自体がBluetooth LE機器およびBluetooth LEを利用したサービスに対応しはじめました。

iOS7から提供されたiOSが担当するBluetooth LEの機能は:

  • Apple Notification Center Service (ANCS)
  • iBeacon
  • Gameコントローラ (MFi)
  • HID over BLE(キーボードなどの入力装置)

です。今回はこのうちの、ANCSについて解説します。

Appleのドキュメントに詳細があります: https://developer.apple.com/library/ios/documentation/CoreBluetooth/Reference/AppleNotificationCenterServiceSpecification/

Apple Notification Center Serviceの目的

The Apple Notification Center Service (ANCS)の目的は、Bluetooth LEでiOSデバイスに接続するBluetoothアクセサリーに、iOSが出力する様々な通知(メールやFacebookなどの新着、電話着信など)にアクセスする簡便な方法を提供することです。

ANCSの設計原則は、Simplicity, Efficienty そして Scalabilityの3つです。LEDが光るだけの簡単なアクセサリから、液晶表示器がある強力な周辺機器まで、様々な周辺デバイスにサービスを提供します。

ANCSは、Bluetooth LEの規格にあるGATTを使います。特定の、閉じた技術は使っていません。GATTクライアントとして振る舞う周辺機器は、iOSデバイスが提供するANCSを通して、通知サービスの発見と接続そしてアクセスができます。

具体的になにができるのか

iOSの通知の取得と、その通知の詳細情報の取得ができます。いま定義されているイベントには:

  • 電話着信
  • 不在着信
  • 音声メール
  • ソーシャル
  • スケジュール
  • 電子メール
  • ニュース
  • 健康とフィットネス
  • ビジネスとファイナンス
  • 位置
  • エンターテイメント

があります。また、特定のアプリケーションを指定して、詳細情報を取り出す仕組みがあります。

最も簡単なアクセサリは、電話やメール着信でLEDが光るアクセサリでしょう。昔、携帯電話の電波信号で光るLEDアクセサリがありました。電波の周波数が様々になった現代では実現できないアクセサリになっていましたが、ANCSを使うことで、あの当時にあったアクセサリを現代でもう一度実現できます。

そして腕時計型などのウェアブル機器との連携に不可欠な機能です。単体で3G網に接続できない機器は、スマートフォンをハブとします。スマートフォンからの通知の仕組みとしてANCSは、いかなるアプリケーションにも柔軟に対応できる仕組みとなっています。

サンプルコード

詳しくはサンプルコード: https://github.com/reinforce-lab/CoreBluetooth_samples/tree/master/ANCS/ を参照してください。

このサンプルを試すには、iOS6の端末と、iOS7の端末が必要です。アプリをインストールしたら、まずiOS6の端末で、右のNCというタブを選択して、Connectボタンを押します。そしてiOS7の端末で、左のNPのタブを選択して、Advertisingボタンを押します。しばらくすれば、iOS6の端末で接続が完了するでしょう。デバッグコンソールに、通知情報などが表示されます。

iOS7でのCoreBluetoothは、ANCSをフィルタしてアプリに通知しません。このためNCはiOS6の端末でのみ、実装できます。iOS7のANCSに接続するには、まずiOS7側でアドバタイジングを開始します。このとき、なにもサービスを指定する必要はありません。iOS7の端末に接続できれば、ANCSのサービスが検索できます。

あとは、Appleのドキュメント通りです。

モジュールでANCSのクライアントを開発するには

Nordic semiconductor社のnRF51822の開発SDKに、experimentalですが、ANCSのサンプルコードがあります。nRF Goの開発ボード用で表示周りがLCDを利用するコードになっています。PCA10001で使う場合は、simple_uart.c などでメッセージ出力部分を置換するかします。
SDK5.2以降、ソフトウェアデバイスver6以降を使います。半導体はROM256kB、RAM16kBの品番では、Packet: QF AA, Revison: FA, HWID: 002A 以降のものを使います。

参考情報

購入できる製品では、PebbleとGerminのFenixが、ANCSに対応している、らしい。

iBeaconの解説

このページの解説はKindle本にまとめました。

iBeacon関連企業リスト

モバイルに近接技術を利用した会社が、iBeacon関連でサービス提供をいろいろと開始しています。iBeacon関連企業のリストです。

参考サイトの調査

ドキュメント

位置情報とマッププログラミングガイド (Appleの日本語ドキュメントpdf) https://developer.apple.com/jp/devcenter/ios/library/documentation/LocationAwarenessPG.pdf

WWDC 2013, What’s New in Core Location

WWDC 2012 Staying on Track with Location Services

Passbook

http://passkit.com/ Passbook生成を提供している。

https://developer.apple.com/passbook/

ブログ

Location and Maps Programming Guide

新たな領域観測サービス iBeacon を使ってみる

Github

RadiusNetworks / android-ibeacon-service
Android4.3のBLEのライブラリで、iBeaconの信号を受信するサンプルコード。

daher-alfawares / iBeacon
iPadで動作するビーコンとその表示アプリみたいです。

nicktoumpelis / HiBeacons
iPhoneで動作する。
ビーコン、出す方と受信する方。表で一覧表示。

スマートフォン勉強会@関西のログ

2013年11月2日、大阪梅田での スマートフォン勉強会@関西 の資料です。

スライド

手書きノート

CoreBluetoothの概要

iOSアプリケーション開発

この章は、iOSアプリケーション開発にBluetooth LEを提供するCore Bluetoothフレームワークを解説します。

Core Bluetoothフレームワークは、iOSアプリケーションにBluetoot LEデバイスの発見、接続と読み書きの操作を提供します。このフレームワークが、2章で述べたBluetooth LEの通信規格や振る舞いなどの技術詳細を隠蔽して抽象化するので、アプリケーション開発者はアプリケーション開発だけに注力できます。

iOS5とiOS6で、Core Bluetothフレームワークが対応する機能が大きく異なります。iOS5は、Bluetooth LEのセントラルという役割を提供します。iOS6は、セントラルに加えてペリフェラルという役割も提供します。iOSのバージョンごとの対応を、iOS5およびiOS6のアイコンを節のタイトルに表示して明示します。

アプリケーション開発のBluetooth LE基礎知識

キーホルダや心拍センサなどの一般に販売されているBluetooth LEデバイスをアプリケーションから使う場合、たいていデバイスに接続して操作するためのライブラリが提供されているので、Core Bluetoothフレームワークを意識することはないかもしれません。また、Core BluetoothフレームワークがBluetooth LEを抽象化していますから、Bluetooth LEの基礎知識がなくてもアプリケーションを開発できます。

しかし、Bluetooth LEを使うオリジナルのハードウェアを企画設計する場合は、Bluetooth LEの基礎知識が不可欠です。iOSとBlutooth LEでなにができるかは企画に必要な知識ですし、試作品のハードウェアが意図した振る舞いをしない時に、その原因を明らかにするには知識が必要です。

2章でBluetooth LEそれ自体の技術詳細を述べました。ここでは、iOSアプリケーション開発者からみたBluetooth LEの基礎技術情報をまとめます。

クラシックBluetoothとBluetooth LE

Bluetooth4.0は、Bluetooth3.0までの近接高速通信技術にBluetooth Low Energyの超低消費電力通信技術を統合したものです。Bluetooth3.0までの技術を、Bluetooth LEと区別するために、ここではクラシックBluetoothと呼びます。

クラシックBluetoothがヘッドフォンやファイル交換などに使う、連続したより高速のデータ通信を目指しているのに対して、Bluetooth Low Energyは、少量のデータを低頻度でやりとりする用途に、ハードウェアの低コスト化と、コイン型電池で1〜2年間の連続動作ができる超低消費電力に特化しています。

クラシックBluetoothのプロファイル

iPhoneは、Human Interface Device Profile (HID)などのクラシックBluetoothのプロファイルをサポートします。BluetoothキーボードをiPhoneに接続しても、アプリケーションは、それがBluetooth接続なのか、あるいは他の接続方式なのかを気にせずに、キーボードとして扱うことができます。クラシックBluetoothでは、周辺機器との接続および制御は全てiOSがおこない、アプリケーションから操作する手段はありません。もしも設計したい周辺機器が、定義されたプロファイルのどれかにあてはまるのであれば、クラシックBluetoothの認証制度に従い設計するだけです。

規格で定義されたプロファイルに当てはまらない機器のために、クラシックBluetoothには、任意の通信を提供するシリアルポートプロファイル(Serial Port Profile, SPP)があります。iOSアプリケーションから、このSPPを使うことはできません。iOSデバイスと接続するクラシックBluetoothデバイスを設計するには、Made For iPhone(MFi)プログラムをApple社と締結して、機器の認証ハードウェアと開発ライブラリの提供をうけなくてはなりません。

シリアルポートプロファイルは、単なる通信路を提供するだけです。例えば、Windowsパソコンに、シリアルポートプロファイルがあるクラシックBluetoothデバイスを接続すると、デバイス・マネージャーは、その接続を仮想シリアルポートとして扱います。Windowsパソコンでは、ユーザが、Bluetoothデバイスの仮想シリアルポートのポート番号をアプリケーションに指定します。

iOSの認証ハードウェアは、これがApple社のライセンスをうけた正規製品であることを示すとともに、
この機器が接続べきiOSアプリケーションもiOSに伝えます。この、本来のシリアルポートプロファイルにはない機能があるため、周辺機器は自動的に対応するiOSアプリケーションと接続できます。

Bluetooth LEのプロファイルとプロトコル

Bluetooth LEは、その規格のもとで任意のプロファイルを勝手に定義することができます。例えば、先ほどの体温計のサービスを利用して、iOSアプリケーションの振る舞いの制御を変えれば、室温を計測して熱中症をアラート音で警告する振る舞いをさせることも、できます。プロトコルと、プロファイルという2つの用語があります。プロファイルはBluetooth LEを使うデバイスの振る舞いを示します。プロトコルは、通信の手順やデータ表現を示します。

Bluetooth LEのデバイスの振る舞いは、ジェネリック・アトリビュート・プロファイル(Generic Attribute Profile, GAP)として定義されています。GAPが定義するBluetooth LEデバイスの4つの役割のうち、Core Bluetoothフレームワークでアプリケーション開発者が扱うのはセントラルとペリフェラルの2つです。ペリフェラルは、そのデバイスを発見してもらうためのアドバタイジングを行なう役割です。セントラルは、アドバタイジングをしているデバイスを発見して、そのデバイスに接続する役割です。

通信機能は、機能毎に階層表示したプロトコル・スタックで表されます。

リンク層は隣接するデバイス都の間に信頼できる1本の通信路を確立します。Bluetoothには、他のデバイスのパケットを他のデバイスに中継するトランスポート層はなく、隣接したデバイスとの直接通信のみをサポートします。このリンク層で通信タイミングなどを制御する中心となる役割をマスターと呼び、そのマスターに接続するデバイスの役割をスレーブと呼びます。1つのマスターに複数のスレーブが接続した小さなネットワークを、ピコネットと呼びます。

L2CAP(Logical Link Control and Adaptation Protocol)は、上層にある複数のプロトコルが、お互いの存在を気にせず、それぞれが通信できる論理的な通信路を提供します。TCP/IPネットワーキング・アプリケーション開発で使う、HTTPやFTPなどのプロトコルには、デフォルトのポート番号を指定して通信します。L2CAPの論理的な通信路は、このポート番号の指定に相当します。

アトリビュート・プロトコル(Attribute Protocol, ATT)とジェネリック・アトリビュート・プロファイル(Generic Attribute Profile, GATT)は、デバイスの持つデータの表現と、読み書きの手順を提供します。このレイヤで、データを持っているデバイスをサーバ、サーバの値を読み書きするものをクライアントと呼びます。例えば、Bluetooth LEに対応した心拍センサにiPhoneが接続した場合を考えます。心拍センサーが、心拍というデータを持っているのでサーバになります。iPhoneは、心拍の値を読みにいくクライアントになります。

GATTの、サーバ/クライアントの役割は、リンク層のマスター/スレーブの役割と関係なく割り当てられます。通常は、セントラルはマスターでクライアント、ペリフェラルにはスレーブでサーバ、の役割が割り当てられます。

サービスとキャラクタリスティクス

GATTは、サーバが持つデータを、キャラクタリスティクスという単位で読み書きする仕組みを提供します。また、サーバには多くのキャラクタリスティクスがありますが、そのキャラクタリスティクスをグループ化する、サービスという仕組みも提供します。

サービスは、その機器のハードウェアとしての機能を表します。例えば、体温計があるとします。体温計のハードウェアとしての機能は、温度の計測と、計測が完了した時のアラート音の出力の2つだとします。この場合、温度計測をするサービスが1つ、そして警告音を出すサービスが1つ、あるでしょう。それぞれのサービスには、温度を読み出すキャラクタリスティクス、警告音のOn/Offの指示を書き込むキャラクタリスティクスがあるでしょう。体温計という振る舞いにではなく、ハードウェアとしての機能に、サービスが割り当てられます。

Bluetooth LEのアプリケーションは、GATTの上に作られます。Bluetooth LEの規格認証の範囲はGATTまでです。サーバがどのようなサービスやキャラクタリスティクスを提供するかは、機器のアプリケーションとして実装されます。ですから、機器の開発者は、Bluetooth LEの規格認証のもとで、任意のサービスおよびキャラクタリスティクスを定義して、それを実装できます。

これはiOSアプリケーションでも同じです。iOSアプリケーションは、Core Bluetoothフレームワークを通して、GATTのサービスとキャラクタリスティクスにアクセスできます。iOSアプリケーションは、接続した機器の複数のサービスを組み合わせて、機器の振る舞いを制御します。Bluetooth LEを使うiOSアプリケーションは、パソコンで言うデバイス・ドライバに相当する部分を、アプリケーション内部に持つことになります。

クラシックBluetoothで任意のアプリケーションを作る場合は、勝手なプロファイルを定義できないため、SPPの汎用通信を使うほかありません。しかし、Bluetooth LEは、その規格のもとで任意のプロファイルを勝手に定義することができます。例えば、先ほどの体温計のサービスを利用して、iOSアプリケーションの振る舞いの制御を変えれば、室温を計測して熱中症をアラート音で警告する振る舞いをさせることも、できます。

Bluetooth SIGは、よく使われるサービスやプロファイルを定義しています。例えば、バッテリー残量やアラートの出力のようなサービスが定義されています。必要なプロファイルに使えるサービスがすでに定義されていれば、それを利用することができます。わざわざ定義や開発をする必要はありません。

また、プロファイルは、開発者が任意に定義できますが、これでは特定のメーカや機種を超えた汎用性が得られません。Bluetooth SIGは、それぞれの業界団体から提出された汎用化したプロファイルを公式のプロファイルとして審査承認して、Bluetooth LEの公式のプロファイルの定義とすることで、これを解決します。

Bluetooth LEの最善の使いかた

電力消費量を最小にする

iOSアプリケーション開発は電池消費量を常に注意します。もしもアプリケーションが、量自体は小さくても、定常的にかつ長時間電力を消費すれば、積分すれば電池消費量は大きくなります。携帯されるiOSデバイスでは、ユーザがすぐそれに気づき、直前にインストールしたアプリケーションが原因だろうと、それを削除するかもしれません。

Bluetooth LEは超低消費電力の無線通信技術です。これは、接続したマスターとスレーブで電波の送受信のタイミングを同期することで、高周波回路を動かす時間を最小にしているからです。Bluetooth LEが使う2.4GHz帯の周波回路の動作電流それ自体は、クラシックBluetoothと違いはありません。その稼働時間を最小限に絞ることで、時間平均では超低消費電力になるのです。

Core Bluetoothフレームワークを使う時は、スキャンの期間を必要最小にすることだけに気をつけます。iOSアプリケーション開発者がほかに注意することは、ありません。通信による電力消費量に大きく影響するリンク層の通信パラメータの設定は、iOSが隠蔽するので、iOSアプリケーション開発者が触れることはできません。通信パラメータの設定は、ペリフェラルのファームウェア開発者の担当領域です。

2.4GHzの高周波回路では、送信する信号が自分でわかる送信回路よりも、むしろ電力値が8桁以上も違う信号を受信する受信回路のほうが、消費電流が大きくなります。スキャンは、おそらく近辺にいるだろうペリフェラルが送信しているかもしれないアドバタイジング・パケットを検出するために、受信回路を長い時間動作させます。このため、消費電力を最小にするために、スキャンの期間が必要最小になるように注意をします。

バックグラウンド状態でのデバイスの発見とアドバタイズメント

Bluetooth LEはコイン型電池で年単位の無線通信をし続けられるのが大きな特徴です。この特徴を活かしたアプリケーションとデバイスの協調動作を実現するために、iOSは、iOSアプリケーションがサスペンド状態のときのBluetooth LEデバイスから通知があればそれをユーザに表示する機能と、バックグラウンド動作を提供しています。バックグラウンド動作がデバイスとの連携に重要です。

iOSアプリケーションは、セントラ・ロールおよびペリフェラル・ロールになります。それぞれに、Information property list (Info.plist) fileに指定するバックグラウンド動作のモードが追加されました。バックグラウンド状態のiOSアプリケーションは、Bluetoothのスイッチのオンオフや、リモートのペリフェラルからの通知発生などの、Bluetooth LEに関係するイベント発生の都度、iOSから10秒間のアプリケーション実行時間を与えられて、アプリケーションのイベントに該当するデリゲートが呼び出されます

iOSアプリケーションのフォアグラウンド状態とバックグラウンド状態で、iOSのBluetooth LEの振る舞いが異なることに、注意が必要です。iOSは電力消費量に注意して設計されています。Bluetoooth LEは電力を消費する無線回路を使います。特にiOSアプリケーションが動作し続けるバックグラウンド状態は、少しの電力消費でも時間積分すると大きな電力消費量になります。このため、開発者が不注意で電力を消費してしまわないように、非接続状態でのBluetooth LEの無線利用に対しては、iOS自体に工夫がなされています。

Bluetooth LEで予期せぬ電力消費を生じる場面は、デバイスの発見およびアドバタイズメントをする期間です。いったんBluetooth LEデバイス間の接続が確立すれば、その無線通信による消費電力量はコイン型電池1つで年単位持つ程度のものになります。

iOSアプリケーションがセントラル・ロールならば、バックグラウンド状態では、アドバタイズメントのスキャン周期が12分程度に1回と長くなります。また、アクティブ・スキャンを行いません。このため、リモートのペリフェラルの発見周期が長くなります。またリモートのペリフェラルが、アクティブ・スキャンでのみサービスのUUIDが取れる設計の場合は、サービスを発見できません。

Bluetooth LEの無線は、他のiOSアプリケーションと共有しています。そのため、他のアプリケーションの振る舞いが、バックグラウンド状態での動作に影響を与えることがあります。例えば、フォアグラウンドのiOSアプリケーションがスキャンを開始すると、その時に発見されたデバイスはバックグラウンド状態のiOSアプリケーションにも通知されます。

iOSアプリケーションがペリフェラル・ロールならば、バックグラウンド状態では、iOSが送信するアドバタイジング・データが変更されます。バックグラウンド状態では、ローカル・ネームが送信されません。したがって、もしもリモートのセントラルが、ローカル・ネームでデバイスを検索していると、このペリフェラルを発見できません。

Core Bluetoothフレームワーク

Core Bluetoothフレームワークは、iOSアプリケーションにBluetooth LEデバイスの発見と接続そして通信を提供するフレームワークです。Bluetooth LEの
通信パラメータ設定などの詳細を隠蔽してくれるので、振る舞いのみに注力して開発ができます。

は、アプリケーションのダンプ・レポートから推測したiOSのBluetooth LEの実装です。Bluetooth LEのホストは、BTServerというデーモンが実装しています。Core BLuetoothフレームワークは、iOSアプリケーションとこのBSServerとの間のプロセス間通信(Inter Process Communication, IPC)を提供します。

UUIDとCBUUIDクラス

UUIDは、サーバのように統合するものがなくとも生成できる一意に特定できる128ビットの識別子のことで、IETFのRFC412に詳細があります。Bluetooth LEの通信はATT層のアトリビュートというデータの単位で通信をします。アトリビュートが表す様々なデータ型の識別子に、このUUID(Universally Unique Identifier)を使います。また個別のサービスやキャラクタリスティクスの識別にもUUIDを使います。

このUUIDを表すのがCBUUIDクラスです。CBUUIDクラスのインスタンスは UUIDWithString:クラスメソッドで文字列から生成できます。

1
CBUUID *anyServiceUUID = [CBUUID UUIDWithString: @"7E20767A-30BB-4EB2-A43E-AC318D9A89A0"];

Bluetooth LEはUUIDの16ビットの短縮表現を決めています。これは128ビットのUUID”0000XXXX-0000-1000-8000-00805F9B34FB”のうち、X部分の16ビットだけを抜き出した表現です。短縮形の16ビットのUUIDをX部分に当てはめて、128ビットの本来のUUIDを復元できます。
例えば、0x180Dが割り振られた心拍を表すサービスの本来のUUIDは、0000180D-0000-1000-8000-00805F9B34FBになります。

UUIDWithString:クラスメソッドに16新表記で16ビットのUUIDを文字列で指定すると、この短縮形のUUIDが生成されます。

1
CBUUID *heartRateServiceUUID = [CBUUID UUIDWithString: @"180D"];

16ビットの短縮形UUIDは、無線通信のデータ量の削減が目的です。この16ビットの値は、Bluetooth SIGが割り当てと定義を決めており、ユーザが勝手に利用することはできません。GATTのサーバおよびクライアントは、この16ビットの値を内部で128ビットのUUIDに復元して、UUIDの比較などの処理は、128ビットのUUIDに対して実行されます。

UUIDの生成

任意のサービスまたはキャラクタリスティクスを定義するときには、開発者が128ビットのUUIDを生成して割り当てを決めます。UUIDを生成するネットサービスがありますが、OS Xではuuidgenというコマンドライン・ツールがあります。次のコマンドでターミナルからUUIDを生成できます。

$ uuidgen
71DA3FD1-7E10-41C1-B16F-4430B506CDE7

UUIDはハイフンで区切られたASCII文字列で出力されます。この文字列は、CBUUIDクラスの UUIDWithString:クラスメソッドにそのまま使えます。uuidgenコマンドに引数”-hdr”を指定すると、以下のような、そのままヘッダファイルに貼り付けられるソースコードを出力します。

1
2
3
4
$ uuidgen -hdr
// 5F066077-1DCF-4F13-913A-728584900517
#warning Change the macro name MYUUID below to something useful!
#define MYUUID CFUUIDGetConstantUUIDWithBytes(kCFAllocatorSystemDefault, 0x5F, 0x06, 0x60, 0x77, 0x1D, 0xCF, 0x4F, 0x13, 0x91, 0x3A, 0x72, 0x85, 0x84, 0x90, 0x05, 0x17)

セントラル・マネージャとペリフェラル・マネージャ

iOSアプリケーションはiOS5およびiOS6ではセントラル・ロールを、iOS6ではペリフェラル・ロールになれます。それぞれ役割を提供するのが、CBCentralManagerクラス、CBPeripheralManagerクラスです。

セントラル・マネージャの役割

iOSアプリケーションがセントラル・ロールのとき、その通信制御は CBCentralManagerクラス で行います。Bluetooth LEを使うiOSアプリケーションの処理手順は:

  • ペリフェラルの発見と接続
  • サービスおよびキャラクタリスティクスの検索
  • キャラクタリスティクスへのデータの読み書き
  • キャラクタリスティクスからの変更通知設定

です。CBCentralManagerクラスの役割は:

  • アドバタイジング・データの取得
  • ペリフェラルの発見と接続
  • ペリフェラルの切断

です。ローカル・デバイスにセントラル・ロールを実装するサンプル・コードで、このこの3つの役割の実装を見ていきます。

セントラル・マネージャのインスタンス生成

セントラル・マネージャに対応するものが、CBCentralManagerクラスです。Bluetooth LEの通信を始める前に、CBCentralMangerクラスのオブジェクトにメモリ領域を割り当て、initWithDelegate:queue:メソッドで初期化します。

myCentralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];

initWithDelegate:queue:メソッドの引数は2つあります。最初の引数はセントラル・ロールのイベントを受け取るデリゲートを指定します。ここではselfを指定しています。この引数に指定するインスタンスはCBCentralManagerDelegateを実装します。

2つめのquequeは、通信処理を行なうキューを指定します。nilを指定した場合はメインキューが使われます。もしも、時間がかかるBluetooth LE関連の処理を行なう場合は、その処理がメインキューを止めてしまい、ユーザ・インタフェースを邪魔してしまうため、適当なキューを指定します。

CBCentralManagerクラスのインスタンスはiOSアプリケーションに1つだけ持つようにします。2つ以上を持っても動作するかもしれませんが、おかしな挙動をしたり、またiOSのバージョン更新で動作しなくなるかもしれません。また、アプリケーションがBluetooth LEで通信する間は、CBCentralManagerのインスタンスを保持します。デバイスとの接続が完了したからと、CBCentralManagerを解放しないようにします。

Bluetoothの状態取得

CBCentralManagerのstateプロパティは、Bluetoothの状態を表すCBCentralManagerState列挙型で、その値と意味は次のとおりです:

  • CBCentralManagerStateUnknown = 0,
    • 初期値です。すぐに更新されます。
  • CBCentralManagerStateResetting,
    • システムサービスとの接続が一時的に失なわれました。すぐに更新されます。
  • CBCentralManagerStateUnsupported,
    • Bluetooth Low EnergyのCentral/Clientをサポートしていません。
  • CBCentralManagerStateUnauthorized,
    • このアプリケーションは、Bluetooth Low EnergyのCentral/Client使う認可がありません。
  • CBCentralManagerStatePoweredOff,
    • Bluetoothがオフになっています。
  • CBCentralManagerStatePoweredOn
    • Bluetoothがオンで、かつ、いま利用できます。

CBCentralManagerをインスタンスした直後のstateプロパティは、CBCentralManagerStateUnknown(=0)の初期値です。このstateプロパティが変更されると、CBCentralManagerDelegateプロトコルのcentralManagerDidUpdateStateメソッドが呼び出されます。このメソッドにはCBCentralManagerのインスタンスが渡されます。

CBCentralManagerDelegateプロトコルには、たくさんのメソッドがありますが、必ず実装しなければいけない(required)ものはcentralManagerDidUpdateStateメソッドだけです。その他のメソッドは、オプショナルです。もしもCBCentralManagerDelegateプロトコルのメソッド名をタイプミスしていても、コンパイラは警告を出してくれません。タイプミスは入力補完やドキュメントからのコピーを利用して防止します。

CBCentralManagerのインスタンスを作ると、直ちにstateの値が変更されます。Bluetooth4に対応していないiOSデバイスであれば、stateプロパティはCBCentralManagerStateUnsupportedになります。Bluetooth LEを使うことはできないので、iOSアプリケーションで対処をします。Bluetooth4対応のiOSデバイスであれば、stateプロパティはCBCentralManagerStatePoweredOnまたはCBCentralManagerStatePoweredOffに変更されます。

Bluetoothの電源On/Offは、iOSアプリケーションから操作することはできません。ユーザがiOSの設定アプリケーションから、Bluetoothの電源On/Offができます。ペリフェラルを検索するために、iOSアプリケーションがスキャンを開始したときに、Bluetoothの電源がOffであれば、Bluetoothの電源をOnにする画面が自動で表示されます。設定ボタンを押すと、自分のiOSアプリケーションからiOSの設定アプリケーションに遷移して、Bluetoothの電源設定画面が表示されます。

ペリフェラルのスキャン

セントラルが行なう最初のタスクは、ペリフェラル・デバイスの発見です。ペリフェラル・デバイスは、自分の存在を周囲のセントラル・デバイスに伝えるために、アドバタイジング・パケットを送信しています。CBCentralManagerのscanForPeripheralsWithServices:options:メソッドを呼び出して、セントラルのアドバタイジング・パケットの受信を開始します。

[myCentralManager scanForPeripheralsWithServices:nil options:nil];

scanForPeripheralsWithServices:options:メソッドの引数は2つあります。最初の引数は、ペリフェラルをフィルタリングするためのものです。発見したいサービスのUUIDを、NSArrayで配列にして指定します。サービスはペリフェラルの機能に対応しています。サービスでフィルタリングすることで、セントラルが必要とする機能がある機器のみを、発見できます。この引数にnilを指定すると、フィルタリングせず、発見した全てのペリフェラルが報告されます。Appleは、Core Bluetoothプログラミング・ガイドで、より低消費電力の動作にするために、サービスを指定することを推奨しています。nilを指定することは、推奨していません。

2つめの引数optionsは、スキャンの動作を指定するオプションをNSDictionaryクラスのインスタンスで渡します。NSDictionaryには、オプションの種類をキー値に、そのオプション値を値に設定します。指定できるオプションは、CBCentralManagerScanOptionAllowDuplicatesKey のみで、値にBooleanをとります。この引数がnilのときは、CBCentralManagerScanOptionAllowDuplicatesKey の値をNOに設定したのと同じになります。

CBCentralManagerScanOptionAllowDuplicatesKey の値をYESにすると、ローカルのセントラルデバイスがペリフェラルからのアドバタイジング・パケットを受信するたび、ペリフェラルの発見が通知されます。NOの場合は、初めてアドバタイジング・パケットを受信した時にペリフェラルの発見が通知され、それ以降、同じペリフェラルからアドバタイジング・パケットを受信しても、発見を通知しません。

このオプションは:

  • 非接続で電波強度を知りたいとき
  • ブロードキャスタのデータを取るとき

によく使われます。アドバタイジング・パケットの受信通知では受信信号強度(Received Signal Strength Indicator,RSSI)も通知されます。RSSIから、ペリフェラルとの距離を大雑把に推定できます。ペリフェラルが近くに来た時に初めて接続させたいときなどに、用います。

周囲のBluetooth LEデバイスに非接続で情報を広報するものをブロードキャスターといいます。ブロードキャスタは、位置ビーコンなど、周囲の不特定多数のデバイスに20バイト程度までの少量の同じ情報を伝えます。ブロードキャスタのデータが不変であれば、アドバタイジング・パケットの受信通知は1度だけで済みます。ブロードキャスターまでの位置を大雑把に把握し続けたいとき、またはブロードキャスターのデータが変化するときには、このオプションを使います。

スキャンを一旦開始すると、スキャンし続けます。タイムアウトなど自動的に停止することはありません。スキャンは、iOSアプリケーションが、CBCentralManagerのstopScanメソッドを呼び出して、明示的に停止しなければなりません。

iOSアプリケーションがすでにスキャンを開始しているときに、scanForPeripheralsWithServices:options:メソッドをパラメータを指定して呼び出すと、指定したパラメータで更新されて、動作が切り替わります。

アドバタイジング・パケットの受信

ローカルのセントラルがアドバタイジング・パケットを受信すると、CBCentralManagerDelegateプロトコルのcentralManager:didDiscoverPeripheral:advertisementData:RSSI: メソッドに通知されます。

1
2
3
4
5
6
-(void)centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI {
NSLog(@"Discovered %@", peripheral.name);
...

centralManager:didDiscoverPeripheral:advertisementData:RSSI: メソッドには4つの引数があります。最初の引数はCBCentralManagerクラスのインスタンスを、次の引数はペリフェラルを表すCBperipheralクラスのインスタンスです。3つ目の引数 advertisementData は、アドバタイジング・パケットのデータをおさめたNSDictionaryクラスのインスタンスです。最後のRSSIは受信信号強度を表します。

受信信号強度の値は、次の式で与えられます:

RSSI = 10 * log I(mW) (dBm)

この式のIは、受信信号電力をミリワット単位で表します。RSSIの値は、送信電力、デバイスとの距離等できまる伝搬損失、そして受信感度で決まります。受信信号電力は桁違いに変化するため、扱いやすくするためにRSSIは対数で表現されます。RSSIは、目安として、-30 dBm から-100 dBm までのマイナスの値を取ります。

scanForPeripheralsWithServices:options:メソッドのオプションに、CBCentralManagerScanOptionAllowDuplicatesKeyにYESの値設定していれば、同じペリフェラルのアドバタイジング・パケットを受診するたび、このcentralManager:didDiscoverPeripheral:advertisementData:RSSI: メソッドが呼び出されます。これは変化するアドバタイジング・データやRSSIのモニタリングに使います。

アドバタイジング・データ

アドバタイジング・パケットのペイロードは、AD structureの配列です。AD structureは、1オクテットのAD typeと、それにつづくAD Dataというバイト・データです

scanForPeripheralsWithServices:options:メソッドの3つ目の引数advertisementDataは、アドバタイジング・パケットから読みだしたデータを収めたNSDictionaryクラスのインスタンスです。キー値にAD typeに対応した文字列が、バリューにはキー値に対応するクラスのインスタンスが入ります。アドバタイジング・パケットにどのようなタイプの情報を入れるかは、ペリフェラル次第です。もしもアドバタイジング・パケットにキー値に対応する値がない場合は、そのキーバリューペアはありません。

次の6つのキー値が CoreBluetooth/CBAdvertisementData.h に定義されています。

  • CBAdvertisementDataLocalNameKey
  • CBAdvertisementDataTxPowerLevelKey
  • CBAdvertisementDataServiceUUIDsKey
  • CBAdvertisementDataOverflowServiceUUIDsKey (iOS6以降)
  • CBAdvertisementDataManufacturerDataKey
  • CBAdvertisementDataServiceDataKey

CBAdverisementDataLocalNameKey のバリューは、ペリフェラルのローカル・ネームを表す、NSStringクラスのオブジェクトです。ローカル・ネームは、特定のペリフェラルを探すのによく使います。機種番号であったり、あるいはシリアル番号を含む何かの識別文字列が割り当てられます。

AD typeには、完全なローカル名を表すタイプと、ローカル名が長すぎてアドバタイジング・パケットに収まりきらない場合に使う短縮形の2つのタイプがあります。AD typeがいずれの値でもCBAdverisementDataLocalNameKey の1つのキーで、ローカル名が返されるので、ここでそれらを区別する方法はありません。

CBAdvertisementDataTxPowerLevelKey のバリューは、ペリフェラルの送信電力を表すNSNumberクラスのインスタンスです。送信電力の単位はdBmです。ペリフェラルとの距離の推定に、送信電力値を使います。

セントラルのスキャンには、パッシブ・スキャンとアクティブ・スキャンがあります。ペリフェラルが送信するアドバタイジング・パケットを受信するだけなのが、パッシブ・スキャンです。セントラルからペリフェラルに、更にアドバタイジング・パケットをリクエストするのが、アクティブ・スキャンです。

CBAdvertisementDataServiceUUIDsKey のバリューは、ペリフェラルのサービスを表すCBUUIDクラスのインスタンスの配列(NSArrayクラスのインスタンス)です。CBAdvertisementDataOverflowServiceUUIDsKey はiOS6移行にあるキー値です。アクティブ・スキャンで得られた、ペリフェラルのサービスを表すCBUUIDクラスのインスタンスの配列(NSArrayクラスのインスタンス)です。

周囲の不特定多数のレシーバに一方向にデータを伝える役割をブロードキャスタと呼びます。位置ビーコンなどに使われます。アドバタイジング・パケットは、ペリフェラルの存在を周囲に知らせる以外に、ブロードキャストに使われます。

CBAdvertisementDataManufacturerDataKey のバリューは、ペリフェラルの設計製造会社が設定できる任意のバイト・データを表すNSDataクラスのインスタンスです。Bluetooth SIGが企業に割り当てた2バイトの識別子に任意のデータが続きます。CBAdvertisementDataServiceDataKeyのバリューは、NSDataクラスのインスタンスで、そのバイト・データは先頭2バイトがサービスを表す16ビットのUUIDが、その後にサービスに関連する任意のバイト・データが続きます。

ブロードキャスティングに、いずれのキー値が使われるかは、ペリフェラルの実装次第です。もしも、その仕様が製造業者が独自に定義したものであれば、CBAdvertisementDataManufacturerDataKey が使われるでしょう。仕様が特定の製造会社に縛られない一般的なもので、Bluetooth SIGが承認したサービスの定義があるならば、CBAdvertisementDataServiceDataKey が使われるでしょう。

ペリフェラルへの接続

ペリフェラルが発見できれば、次にそれが接続したいペリフェラルかを判定して、接続処理を行います。

1
2
3
4
5
6
7
8
9
10
-(void)centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI {
...
NSString *localName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
if(localName != nil && [localName isEqualToString:@"devide name"] ) {
_peripheral = peripheral;
[myCentralManager connectPeripheral:peripheral options:nil];
}

ペリフェラルが接続先か否かは、引数advertisementDataの内容で判別します。ローカル・ネームが対応機種名かで判定する実装が、よく使われます。接続するならば、CBCentralManagerクラスのconnectPeripheral:options: メソッドを呼び出します。

CBPeripheralクラスのインスタンスは、そのペリフェラルの利用が終了するまで、必ずiOSアプリケーションで保持します。上のコードでは、引数peripheralをインスタンス変数 __peripheral_で保持しています。CBperipheralクラスのインスタンスを解放すると、CBCentralManagerは、接続開始処理および接続状態を終了させて通信を切断します。CBperipheralManagerは、CBPeripheralクラスのインスタンスを保持しません。

Bluetooth LEの接続処理は、アドバタイジング・パケットを受信した後に、直ちに接続要求を出さねばなりません。したがって、connectPeripheral:options:メソッドを呼び出しても、接続が完了するのは、次のアドバタイジング・パケットを受信したタイミング以降になります。

ペリフェラルとの接続が確立すると、CBCentralManagerDelegateプロトコルのcentralManager:didConnectPeripheral:メソッドが呼び出されます。この引数peripheralは、connectPeripheral:options:メソッドに指定したCBPeripheralクラスのインスタンスと同じものです

1
2
3
4
- (void)centralManager:(CBCentralManager *)central
didConnectPeripheral:(CBPeripheral *)peripheral {
NSLog(@"Peripheral connected");
...

接続処理に失敗した場合は、CBCentralManagerDelegateプロトコルのcentralManager:didFailToConnectPeripheral:error:メソッドが呼び出されます。接続失敗の原因は、引数errorで渡されます。

1
2
3
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
NSLog(@"Failed to connect to a Peripheral");
...
サービスの検索

ペリフェラルには様々な機能があります。その機能それぞれを表すのが、Bluetooth LEのサービスです。ペリフェラルと接続できたならば、次は必要なサービスを検索します。

1
2
3
4
5
- (void)centralManager:(CBCentralManager *)central
didConnectPeripheral:(CBPeripheral *)peripheral {
...
peripheral.delegate = self;
[peripheral discoverServices:nil];

ペリフェラルの処理結果は、デリゲートのメソッド呼び出しで非同期に返されます。このコードはCBPeripheralDelegateプロトコルを実装したselfを、引数peripheralのdelegateプロパティに設定します。

CBPeripheralクラスのdiscoverServices:メソッドを呼び出して、サービスの検索を開始します。ペリフェラルの全てのサービスを検索するならば、引数にnilを指定します。検索するサービスを指定するならば、NSArrayクラスのインスタンスで、指定したいサービスのUUIDを設定したCBUUIDクラスのインスタンスを配列にして、引数に渡します。

ペリフェラルを発見した時のアドバタイジング・パケットのサービスUUIDよりも、このdiscoverServices:メソッドで発見できるサービスのほうが、多いかもしれません。これは、128ビットのサービスUUIDはアドバタイジング・パケットに1つしか入らないため、アドバタイジング・パケットですべてのサービスを取得できるとは、限らないからです。

Core Bluetoothフレームワークは、discoverServices:メソッドに、サービスを指定することを推奨しています。サービスの検索には通信時間と処理時間がかかります。検索対象のサービスを事前に指定することで、それらをより短くできます。

サービスを発見すると、そのCBPeripheralのインスタンスのdelegateプロパティに設定したインスタンスの、CBPeripheralDelegateプロトコルのperipheral:didDiscoverServices: メソッドが呼ばれます。

1
2
3
4
5
6
7
8
- (void)peripheral:(CBPeripheral *)peripheral
didDiscoverServices:(NSError *)error {
for (CBService *service in peripheral.services) {
NSLog(@"Discovered service %@", service);
if ([service.UUID.data isEqualToData:_targetServiceUUID.data]) {
[peripheral discoverCharacteristics:nil forService:service];
}
...

引数peripheralのservicesプロパティは、NSArrayクラスのインスタンスで、その内容はCBServiceクラスのインスタンスの配列です。もしもサービス検索でエラーが発生していれば、引数errorにその内容が入ります。

キャラクタリスティクスの検索

使いたいサービスの検索が完了すれば、次はサービスそれぞれの、アクセスしたいキャラクタリスティクスを取得していきます。サービスごとに検索したいキャラクタリスティクスは異なるので、まず、CBPeripheralクラスのインスタンスのservicesプロパティのインスタンスが、どのサービスに対応しているのかを判別しなければなりません。これは、CBServiceクラスのインスタンスのUUIDプロパティの一致で判定できます。

1
2
3
4
5
6
7
8
- (void)peripheral:(CBPeripheral *)peripheral
didDiscoverServices:(NSError *)error {
for (CBService *service in peripheral.services) {
NSLog(@"Discovered service %@", service);
if ([service.UUID.data isEqualToData:_targetServiceUUID.data]) {
[peripheral discoverCharacteristics:nil forService:service];
}
...

CBPeripheralクラスの discoverCharacteristics:forService: メソッドを呼び出してキャラクタリスティクスを検索します。このメソッドには2つの引数があります。最初の引数は、検索したいキャラクタリスティクスのUUIDの配列を指定します。forService:には検索対象のサービスを指定します。

discoverCharacteristics:forService: メソッドの最初の引数にnilを指定すると、そのサービスの全てのキャラクタリスティクスを検索します。iOSアプリケーションが、そのペリフェラルをどう使うかは、設計時点で決まるので、ここでnilを渡すことは、あまりありません。キャラクタリスティクスの検索には、通信時間がかかり電池を消費するため、Apple社のプログラミングガイドは、キャラクタリスティクスのUUIDを指定することを推奨しています。

キャラクタリスティクスが検索できると、CBPeripheralDelegateプロトコルのperipheral:didDiscoverCharacteristicsForService:error: メソッドが呼ばれます。

1
2
3
4
5
6
7
- (void)peripheral:(CBPeripheral *)peripheral
didDiscoverCharacteristicsForService:(CBService *)service
error:(NSError *)error {
for (CBCharacteristic *characteristic in service.characteristics) {
NSLog(@"Discovered characteristic %@", characteristic);
...
} ...

キャラクタリスティクスは、CBCharacteristicクラスのインスタンスで与えられます。引数serviceのcharacteristicsプロパティは、このCBCharacteristicのインスタンスをNSArrayで配列にしたものです。キャラクタリスティクスの取得時にエラーが発生した場合は、引数errorでエラー情報が渡されます。正常動作時は、引数errorの値はnilです。

キャラクタリスティクスの読み出し

ペリフェラルの値の読み書きは、キャラクタリスティクスを通して行います。例えば、ペリフェラルが心拍計なら、心拍計速のサービスのなかに、心拍数を表すキャラクタリスティクスがあります。

キャラクタリスティクスの値読み出し方法には、直接読み出しと、サブスクリプションの2つがあります。直接読み出しは、セントラルからペリフェラルに読み出し要求を送信して、それを受けたペリフェラルがセントラルにキャラクタリスティクスのデータを返す方法です。サブスクリプションは、ペリフェラルがキャラクタリスティクスの値を変更したときに、ペリフェラルがセントラルに、更新された値を送信する方法です。

Bluetooth LEの通信プロトコルには、キャラクタリスティクスの読み出し方法には、ノーティフィケーションとインディケーションの2つがあります。Core Bluetoothフレームワークのキャラクタリスティクスの読み出しでは、この2つを区別する方法はありません。用語を区別して混同しないように、Core Blutoothフレームワークのペリフェラルからセントラルの変更通知を、ここではサブスクリプションと呼びます。

キャラクタリスティクスの値が固定値ならば、接続時に1度読み出せばいいので、直接読み出しをします。値が変化するキャラクタリスティクスを常にモニタしたいならば、サブスクリプションを使います。セントラルが一定周期で読み出しをするポーリングに比べて、値の変更時に通知してくれるサブスクリプションは、無駄に無線通信することがありません。

キャラクタリスティクスの読み出しには、CBPeripheralクラスのreadValueForCharacteristic:メソッドを使います。引数には、読み出したいキャラクタリスティクスに対応するCBCharacteristicのインスタンスを与えます。

NSLog(@"Reading value for characteristic %@", interestingCharacteristic);
[peripheral readValueForCharacteristic:interestingCharacteristic];

キャラクタリスティクスの読み出し結果は、CBPeripheralDelegateプロトコルのperipheral:didUpdateValueForCharacteristic:error:メソッドで返されます。

1
2
3
4
5
6
- (void)peripheral:(CBPeripheral *)peripheral
didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic
error:(NSError *)error {
NSData *data = characteristic.value;
// parse the data as needed
...

読み出しに成功すれば引数errorはnilです。もしも失敗した場合は、引数errorにはエラー内容を表すNSErrorのインスタンスが与えられます。読み出しに成功していれば、読み出し値は、引数characteristicのvalueプロパティから取り出せます。

読み出しでは、全てのキャラクタリスティクスに読み出し権限があるとは限らないことに注意します。キャラクタリスティクスには、それぞれにパーミションが設定されています。パーミションの、読み出しフラグと、サブスクリプション権限のフラグは、それぞれ独立して設定できます。このため、読み出しはできるがサブスクリプションはできない設定や、逆に、読み出しができないがサブスクリプションはできる設定が、ありえます。読み出し権限がないキャラクタリスティクスに直接読み出しをした場合、あるいはサブスクリプション権限のフラグがない場合にサブスクリプションした場合は、エラーになります。

キャラクタリスティクスのパーミション設定は、列挙型CBCharacteristicProperties のpropertiesプロパティから読み出せます。列挙型CBCharacteristicPropertiesには、読み出し権限以外にも多くの権限が定義されています。それぞれの権限はビット・フラグで、論理和で設定できます。

読み出し権限があることを確認するならば、CBCharacteristicPropertyRead とCBCharacteristicのpropertyプロパティの論理和が0でないことを、確認します。通常は、ペリフェラルの仕様書に、キャラクタリスティクスのパーミション設定が明記されています。ですから、iOSアプリケーションでパーミション設定を調べることは、あまりありません。

キャラクタリスティクスの値変更通知を受け取るには、CBPeripheralクラスのsetNotifyValue:forCharacteristic:メソッドを使います。サブスクリプションの権限がないキャラクタリスティクスに、このメソッドを呼び出しても、なにも変化しません。

[peripheral setNotifyValue:YES forCharacteristic:interestingCharacteristic];

setNotifyValue:forCharacteristic:メソッドには引数が2つあります。最初の引数は、通知を受け取るか受け取らないかを指定するBooleanの値です。YESまたはNOを与えます。2つ目の引数は、通知を受けたいキャラクタリスティクスのCBCharacteristicのインスタンスです。

通知設定のデフォルト値はNOです。また、セントラルとの通信が切断した時に、ペリフェラルは通知設定をデフォルト値NOに初期化します。ですから、サブスクリプションをするならば、セントラルはペリフェラルに接続した都度、設定します。

サブスクリプションをYESに設定すると、キャラクタリスティクスの値が更新されると、その更新値が
CBPeripheralDelegateプロトコルの peripheral:didUpdateNotificationStateForCharacteristic:error: メソッドで通知されます。

1
2
3
4
5
6
- (void)peripheral:(CBPeripheral *)peripheral
didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic
error:(NSError *)error {
if (error) {
NSLog(@"Error changing notification state: %@",
} ...

引数の意味や使いかたは、値読み出しの peripheral:didUpdateValueForCharacteristic:error:メソッドのそれと、同じです。

キャラクタリスティクスへの書き込み

ペリフェラルへの値の書き込みは、読み込みと同じくキャラクタリスティクスを通じて行います。値の書き込みは、ペリフェラルに保存されているデータを変更する意味のほか、例えばエアコンの赤外線リモコンに開始/停止の動作指定や温度設定のボタンがあるように、動作や目標値を指示する意味もあります。

1
2
NSLog(@"Writing value for characteristic %@", interestingCharacteristic); [peripheral writeValue:dataToWrite forCharacteristic:interestingCharacteristic
type:CBCharacteristicWriteWithResponse];

キャラクタリスティクスに書き込む CBPeripheral クラスの writeValue:forCharacteristic:type: メソッドには、3つの引数があります。最初の引数には書き込みたいバイト・データを収めたNSDataのインスタンスを、2つ目の引数には書き込み対象のキャラクタリスティクスの CBCharacteristic のインスタンスを、最後の3つ目の引数には書き込みタイプを表す定数を与えます。

サンプルコードの最初の引数dataToWriteのバイト・サイズは20バイト以下にします。キャラクタリスティクスに書き込めるバイト・データのサイズは20バイト以下です。20バイトよりも大きいデータを与えた場合は、その部分のバイトデータはペリフェラルに送信されません。

キャラクタリスティクスに書き込めるデータ・サイズの上限は、Bluetooth LEのアトリビュート・プロトコル(Attribute Protocol, ATT)によるものです。ATTのプロトコル・データ・ユニット(Protocol Data Unit, PDU)の最大長 Maximum Transfer Unit(MTU)、ATT_MTU と表します、はデフォルト値が23バイトです。ヘッダを除くと、1つのPDUで送れるデータ・サイズは20バイトになります。これが、キャラクタリスティクスに1回で書き込めるデータ・サイズを決めています。

ATTには、セントラルとペリフェラルがそれぞれのATT_MTUのサイズを交換しあって、デフォルト値23バイトよりも大きなATT_MTUを扱えるようにする仕組みがあります。しかしiOS5およびiOS6は、このATT_MTUのサイズ交換に対応していません。

3つ目の引数typeは列挙型 CBCharacteristicWriteType の値です。この列挙型は、2つの値 CBCharacteristicWriteWithResponse (= 0)および CBCharacteristicWriteWithoutResponse を定義しています。このサンプルコードは、引数typeに CBCharacteristicWriteWithResponse を指定しています。

この書き込みタイプは、Bluetooth LEの通信プロトコルの2つの書き込み方法に対応しています。CBCharacteristicWriteWithResponseを指定すると、セントラルはライト・リクエストでペリフェラルに書き込みを行います。ペリフェラルは、書き込み処理の成功失敗に関係なく、処理結果をセントラルに返します。この結果はデリゲートを通じてiOSアプリケーションに返されます。これは、ペリフェラルの不揮発メモリの書き込みなどの、書き込みの完了を必ず確認しなければならない場合に使います。

CBCharacteristicWriteWithoutResponse を指定すると、セントラルは、ライト・コマンドを使って書き込みます。ペリフェラルは、書き込み処理が成功しても失敗しても、セントラルに結果を返すことはありません。これは、例えばエアコンのリモコンの動作開始指示ボタンのような、動作を指示する場合などに使われます。

書き込みをしたのに、ペリフェラルの動作に反映されないなどの、書き込み処理の失敗は、大抵ペリフェラルの都合によるものです。セントラルのライト・コマンドが通信路で失われて、ペリフェラルが受信できないことは、ありえません。接続している限り、リンク層がセントラルとペリフェラル間に信頼できる通信を提供しています。コマンドは無視してもよいため、処理時間がないなどの理由があると、ペリフェラルはコマンドの処理をスキップするかもしれません。

キャラクタリスティクスが、どの書き込みのタイプに対応しているかは、キャラクタリスティクスのパーミション設定で判別ができます。CBCharacteristicクラスのpropertyプロパティと、
CBCharacteristicPropertyWrite との論理積が0でなれば(ビットが立っていれば)、そのキャラクタリスティクスはレスポンスありの書き込み対応しています。CBCharacteristicPropertyWriteWithoutResponseとの論理積が0でないならば、レスポンスなしの書き込みに対応しています。この2つのパーミションは、それぞれ独立に設定できるので、キャラクタリスティクスが書き込み可能であれば、パーミション設定には3通りあります。

writeValue:forCharacteristic:type: メソッドの引数typeに CBCharacteristicWriteWithResponse を指定したとき、CBPeripheralDelegateプロトコルのperipheral:didWriteValueForCharacteristic:error: メソッドに、書き込み結果が返されます。

1
2
3
4
5
6
- (void)peripheral:(CBPeripheral *)peripheral
didWriteValueForCharacteristic:(CBCharacteristic *)characteristic
error:(NSError *)error {
if (error) {
NSLog(@"Error writing characteristic value: %@",
} ...

引数は3つあります。読み込み処理の場合と同じように、エラーが発生すれば引数errorにその内容が渡されます。正常に処理できたならば、引数errorはnilです。

ペリフェラル・マネージャーの役割

Bluetooth LEにはセントラルとペリフェラルという2つの役割があります。iOS6から、iOSアプリケーションがペリフェラル・ロールになれるCBPeripheralManagerクラスが提供されています。ペリフェラル・ロールは、Bluetooth LEの、リンク層のスレーブ、ジェネリック・アトリビュート・プロトコル層ではサーバの役割を担います。

ペリフェラル・ロールのiOSアプリケーションは:

  • アドバタイジング・パケットの送信
  • セントラルとの接続および切断
  • 読み出しおよび書き出し要求の処理
  • 通知処理

を行います。CBPeripheralManagerクラスの役割は:

  • アドバタイズ
  • サービスおよびキャラクタリスティクスのデータベースの作成と公開
  • セントラルからのリクエストおよびコマンドの処理

です。ローカル・デバイスにペリフェラル・ロールを実装するサンプル・コードで、このこの3つの役割の実装を見ていきます。

ペリフェラルのマネージャーを開始する

ペリフェラルの役割はCBPeripheralManagerクラスが提供します。CBPeripheralManagerクラスのinitWithDelegate:queue:メソッドでインスタンスを生成します。

myPeripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];

initWithDelegate:queue:メソッド
の引数は2つあります。最初の引数はペリフェラル・ロールのイベントを受け取るCBPeripheralManagerDelegateプロトコルを実装したデリゲートを指定します。ここではselfを与えています。2つめのquequeは、通信処理を行なうキューを指定します。nilを指定した場合はメインキューが使われます。

CBPeripheralManagerクラスのインスタンスは、iOSアプリケーションに1つだけ持つようにします。CBPeripheralManagerを2つ以上インスタンスした時の振る舞いがどうなるかは、わかりません。

CBPeripheralManagerDelegateプロトコルは、必ず実装しなければならないperipheralManagerDidUpdateState:メソッドと、その他のオプションのメソッドがあります。peripheralManagerDidUpdateState:メソッドは、Bluetoothの電源やペリフェラル・マネージャーの状態を伝えます。その他のメソッドは、ローカルのデータベースに接続およびアクセスするセントラルについての情報を提供します。

ペリフェラル・マネージャーの状態

CBPeripheralManagerのstateプロパティは、ペリフェラル・マネージャーの状態を伝える列挙型CBPeripheralManagerStateの値です。CBPeripheralManagerのインスタンスを作成したときは、stateプロパティの値はCBPeripheralManagerStateUnknownです。このstateプロパティが変化すると、その都度CBPeripheralManagerDelegateプロトコルのperipheralManagerDidUpdateState:メソッドが呼ばれます。

列挙型CBPeripheralManagerStateの値とその意味は次のとおりです:

  • CBPeripheralManagerStateUnknown
    • インスタンスした直後の、初期値を示します。すぐにペリフェラル・マネージャーの状態を表す値に変更されます。
  • CBPeripheralManagerStateResetting
    • システムサービスとの接続が一時的に失われたことを示します。この値はすぐに更新されます。
  • CBPeripheralManagerStateUnsupported
    • この機種が、Bluetooth LEのスレーブ/サーバをサポートしていないことを示します。
  • CBPeripheralManagerStateUnauthorized
    • このアプリケーションに、Bluetooth Low Energy のスレーブ/サーバを使う権限がありません。
      -CBPeripheralManagerStatePoweredOff
    • Bluetoothがオフになっています。
      ー CBPeripheralManagerStatePoweredOn
    • BluetoothがONで、利用できます。

Bluetooth LEに対応した機種であれば、ペリフェラル・マネージャーの状態は、CBPeripheralManagerStatePoweredOn状態とCBPeripheralManagerStatePoweredOff状態のいずれかです。

ペリフェラル・マネージャーは、アドバタイジングを開始する前に、ローカルのデータベースを構築してサービスおよびキャラクタリスティクスの設定を行います。この設定は、CBPeripheralManagerStatePoweredOn状態のときのみ、実行できます。

もしもペリフェラル・マネージャーがアドバタイジングをしている間に、stateプロパティがCBPeripheralManagerStatePoweredOff状態になると、アドバタイジングは停止されます。
電源がOnになっても、アドバタイジングは自動的に再開されません。ペリフェラル・マネージャーが明示的にアドバタイジングを再開します。また、Off状態になった時に、ローカル・データベースは全てクリアされます。このため、ペリフェラル・マネージャーは、サービスも再度追加しなければいけません。

サービスとキャラクタリスティクスの構築

Bluetooth LEのペリフェラルのデータベースは、ハンドル、タイプ、バリューの3つのフィールドで構成されるアトリビュートの集合です。アトリビュート・プロトコルが、タイプやハンドルを指定してアトリビュートにアクセスするプロトコルを提供しています。そして、ジェネリック・アトリビュート・プロファイルは、このアトリビュートを使って、サービスとキャラクタリスティクスという概念を導入します。キャラクタリスティクスは、値を保持するものです。サービスはキャラクタリスティクスの集合を表します。

iOSアプリケーションが、内部のデータを外部に公開するには、まずペリフェラル・マネージャーのデータベースを構築します。セントラル・ロールでは、サービスおよびキャラクタリスティクスは、それぞれCBServiceクラスおよびCBCharacteristicクラスに対応していました。ペリフェラル・マネージャーは、サービスおよびキャラクタリスティクスの編集に、それぞれCBMutableServiceクラスおよびCBMutableCharacteristicクラスを使います。CBMutableServiceクラスはCBServiceクラスを、またCBMutableCharacteristicクラスはCBCharacteristicクラスを継承します。

まずサービスとキャラクタリスティクスのUUID、そしてキャラクタリスティクスのパーミション設定と役割を定義します。UUIDを表すCBUUIDクラスおよびUUIDの生成方法はで述べました。Bluetooth SIGが公開しているサービスを実装するならば16ビットのUUIDを使います。任意のサービスを定義するならば128ビットのUUIDを生成します。

まずCBMutableCharacteristcクラスのインスタンスを生成します。CBMutableCharacteristicクラスのinitWithType:properties:value:permissions:メソッドを使います。

1
2
3
4
myCharacteristic =
[[CBMutableCharacteristic alloc] initWithType:myCharacteristicUUID
properties:CBCharacteristicPropertyRead
value:myValue permissions:CBAttributePermissionsReadable];

initWithType:properties:value:permissions:メソッドには引数が4つあります。最初の引数initWithTypeはキャラクタリスティクスのUUIDを表すCBUUIDのインスタンスを与えます。引数valueは、キャラクタリスティクスの値を表すNSDataのインスタンスを与えます。引数propertiesには、キャラクタリスティクスの属性をCBCharacteristicProperties列挙型の値で与えます。引数permissionsには、キャラクタリスティクスのパーミションをCBAttributePermissions列挙型の値で与えます。この2つの列挙型は、いずれも列挙型の複数の値を論理和でまとめて指定できます。

引数valueがnilの場合は、そのキャラクタリスティクスの値は、変化するものとされます。リモートのセントラルがキャラクタリスティクスの値を読み出すと、それがデリゲートに通知されます。デリゲートに、値の返信処理の責任があります。

引数valueにNSDataのインスタンスを与えると、Core Bluetoothフレームワークは、そのキャラクタリスティクスの値は固定値として扱います。キャラクタリスティクスのプロパティは自動的に読み込み可能になります。引数valueの値はキャッシュされて、リモートがこのキャラクタリスティクスを読み出すと、そのキャッシュされた値が自動的にセントラルに返されます。このとき、ペリフェラル・マネージャーはデリゲートのメソッドを呼び出しません。

サービスは、キャラクタリスティクスの集合です。CBMutableServiceクラスのinitWithType:primary:メソッドでインスタンスを生成します。

myService = [[CBMutableService alloc] initWithType:myServiceUUID primary:YES];
myService.characteristics = @[myCharacteristic];

initWithType:primary:メソッドは2つの引数をとります。最初の引数は、そのサービスのUUIDを表すCBUUIDのインスタンスです。2つ目の引数はサービスがプライマリ・サービスかを示すBoolean型の値です。このサンプル・コードはプライマリ・サービスを指定しています。引数primaryをNOにすると、セカンダリ・サービスの指定になります。

このプライマリ・サービスとセカンダリ・サービスは、ペリフェラル・マネージャー内部のサービス定義で使われるものです。リモートのセントラルから見えるのは、プライマリ・サービスだけで、セカンダリ・サービスは見えません。セカンダリ・サービスは、補助的なキャラクタリスティクスをペリフェラル・マネージャー内部でまとめるのに用います。

サービスへのキャラクタリスティクスの追加は、CBMutableServiceのインスタンスのcharacteristicsプロパティに、CBMutableCharacteristcの配列を設定しておこないます。

キャラクタリスティクスのコンフィグレーション

リモートのセントラルから見える、ローカルのキャラクタリスティクスの振る舞いは、パーミションの設定で決まります。

  • セントラルにキャラクタリスティクスをサブスクライブさせるのを許可する
  • ペアリングしていないセントラルからのアクセスを制限、センシティブなもの

もしもローカルのキャラクタリスティクスの値が、しばしば変更されるものならば、リモートのセントラルにサブスクライブさせることを推奨します。そのために、キャラクタリスティクスにサブスクライブを許可するパーミション設定が必要です。これは、CBCharacteristicのpropertyプロパティに、CBCharacteristicPropertyNotifyを設定します:

1
2
3
4
myCharacteristic = [[CBMutableCharacteristic alloc]
initWithType:myCharacteristicUUID
properties:CBCharacteristicPropertyRead | CBCharacteristicPropertyNotify
value:nil permissions:CBAttributePermissionsReadable];

このサンプルコードはCBCharacteristicのインスタンス生成時に指定しています。

センシティブなデータの扱い

BLEデバイスに個人情報を記録する場合があります。例えばソーシャルメディアのプロファイルを提供するBluetooth LEペリフェラルであれば、メンバーのアカウントや名前、住所といった個人情報を保持するでしょう。そのようなデバイスは、誰もが読み書きできる状態では、困ります。信頼したデバイスのみに読み書きを許可する必要があります。

キャラクタリスティクスのプロパティには、読み書きおよびノーティフィケーションの暗号化を指定できます。

1
2
3
4
5
emailCharacteristic = [[CBMutableCharacteristic alloc]
initWithType:emailCharacteristicUUID
properties:CBCharacteristicPropertyRead
| CBCharacteristicPropertyNotifyEncryptionRequired
value:nil permissions:CBAttributePermissionsReadEncryptionRequired];

このサンプル・コードでは、キャラクタリスティクスは信頼するデバイスからのみ、読み出しおよびサブスクライブを受け付けます。リモートのセントラルがこのキャラクタリスティクスにアクセスすると、ローカルのペリフェラル・マネージャーはリモートのセントラルに、必要な権限がないというエラーを返します。そこで、リモートのセントラル・マネージャーは、次に、暗号化に必要な鍵を交換するため、ペリフェラルにペリフェラルを求めます。ローカルのiOSデバイスは、リモートのデバイスがペアリングを要求していることを、ユーザにダイアログ表示します。ユーザが、それを承認することで、ペアリングとボンディングが完了し、リモートのセントラルは、キャラクタリスティクスを読み出せるようになります。

セントラル・ロールとペリフェラル・ロールが両方共iOSデバイスであれば、セントラルがセキュアなキャラクタリスティクスにアクセスした時点で、それぞれのデバイスに、他のデバイスとのペアリングが必要であるダイアログを表示します。セントラル・ロールのデバイスには、ペリフェラルに入力すべきテキスト・コードが表示されます。ペリフェラル・ロールのデバイスに、そのテキスト・コードを入力してペアリングおよびボンディングが完了すれば、ペリフェラルはそのセントラルを信頼できるデバイスとみなします。

ペリフェラル・マネージャーへのサービス追加

キャラクタリスティクスを設定したCBMutableCharacteristcクラスのインスタンスができれば、次はペリフェラル・マネージャーのデータベースに、それらのサービスを追加します。これには、CBPeripheralManagerクラスのaddService:メソッドを使います。

[myPeripheralManager addService:myService];

ペリフェラル・マネージャーにaddService:メソッドでサービスとキャラクタリスティクスを追加すると、その内容はペリフェラル・マネージャーにキャッシュされて、変更することはできません。複数のサービスが複数ある場合はaddService:メソッドを繰り返し呼び出します。

ペリフェラル・マネージャーのデリゲートがperipheralManager:didAddService:error:メソッドを実装していれば、ペリフェラル・マネージャーはサービスの追加処理が完了するつど、このメソッドを呼び出します。もしもサービスの追加に失敗した場合は、このメソッドから原因を取得できます。

1
2
3
4
5
6
- (void)peripheralManager:(CBPeripheralManager *)peripheral
didAddService:(CBService *)service
error:(NSError *)error {
if (error) {
NSLog(@"Error publishing service: %@", [error localizedDescription]);
} ...
アドバタイズメントの開始と停止

周囲にいるかもしれないセントラルにペリフェラルの存在を伝えるために、CBPeripheralManagerクラスのstartAdvertising:メソッドで、アドバタイズメントを開始します。

[myPeripheralManager startAdvertising:@{ CBAdvertisementDataServiceUUIDsKey :
@[myFirstService.UUID, mySecondService.UUID] }];

startAdvertising:メソッドの引数はオプションを指定したNSDictionaryのインスタンスです。このサンプル・コードでは、CBAdvertisementDataServiceUUIDsKey をキー値に、サービスのUUIDに対応するCBUUIDの配列をバリューにしています。

Bluetooth LEのアドバタイズメント・パケットのデータ・タイプは、フラグ、ローカル名、製造者特有のデータ、送信電力およびサービスUUIDの配列の5種類で、CBAdvertisementData.h に、それぞれに対応するキー値が定義されています。

startAdvertising:メソッドの引数の辞書に指定できる値は、 CBAdvertisementDataLocalNameKey と CBAdvertisementDataServiceUUIDsKey の2つです。CBAdvertisementDataLocalNameKey は、デバイスのローカル名を表し、NSStringのインスタンスをバリューに設定します。CBAdvertisementDataServiceUUIDsKey はサービスUUIDの配列を表し、CBUUIDの配列をバリューに設定します。

startAdvertising:メソッドを呼び出すと、ペリフェラル・マネージャーはデリゲートのperipheralManagerDidStartAdvertising:error:メソッドを呼び出します。もしもエラーがありアドバタイズメントが開始出きない場合は、引数errorで詳細情報が渡されます。

1
2
3
4
5
- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral
error:(NSError *)error {
if (error) {
NSLog(@"Error advertising: %@", [error localizedDescription]);
} ...

Core Bluetoothフレームワークは、下層の通信の詳細を隠すため、iOSアプリケーションから、アドバタイズメント・パケットの周期を設定することはできません。また、アドバタイズメントは、パケット・サイズに制約があるため、データ・サイズにも制約があることに注意が必要です。。さらに、iOSアプリケーションがフォアグラウンドかバックグラウンドかにより、アドバタイズメント・パケットの内容が異なります。

iOSアプリケーションがフォアグラウンド状態ならば、アドバタイズメント・パケットの最大データサイズ28バイトを、任意のデータ・タイプの組み合わせで使えます。もしも28バイトを超える場合は、ローカル・ネームに対してのみ、スキャン・レスポンスの10バイトの領域を使うことが可能です。ここでのデータ・サイズは、データ・タイプごとに2バイトのヘッダ情報が付加された後のサイズであることに、注意が必要です。

アドバタイズメント・パケットの28オクテットの領域に収まりきらなかったサービスUUIDsは、スキャン・レスポンスの領域に収められます。したがって、それらの収まりきらかなったサービスUUIDsは、iOSがアクティブ・スキャンをしたときに初めて発見されます。

セントラル・マネージャーのスキャン動作で述べたように、セントラルがペリフェラルを発見した時に、そのペリフェラルが接続対象かの判断は、ローカル・ネームもしくはサービスUUIDsで判断します。また、128ビットのUUIDは、16バイトあるので、アドバタイズメント・パケットに1つしか格納できません。ペリフェラルが意図したように発見されない場合は、startAdvertising:メソッドに指定したデータが、実際にはどのようにアドバタイジング・パケットに格納されているかを、把握することが必要です。

iOSアプリケーションがバックグラウンド状態ならば、アドバタイズメント・パケットにローカル・ネームは含まれません。また、全てのサービスUUIDsは、全てスキャン・レスポンスからのみ取得できます。

読み出しリクエストへの応答


セントラルがペリフェラルのキャラクタリスティクスに読み書きリクエストを送ると、それが固定値でないならば、ペリフェラル・マネージャーはデリゲートのperipheralManager:didReceiveReadRequest:メソッドを呼び出します。キャラクタリスティクスのレスポンス処理は、iOSアプリケーションがすべき処理です。

値が固定値ではないキャラクタリスティクスは、CBMutableCharacteristicクラスのinitWithType:properties:value:permissions:メソッドで、valueにnilを設定したものです。

1
2
3
4
- (void)peripheralManager:(CBPeripheralManager *)peripheral
didReceiveReadRequest:(CBATTRequest *)request {
if ([request.characteristic.UUID isEqual:myCharacteristic.UUID]) {
...

peripheralManager:didReceiveReadRequest:メソッドは2つの引数をとります。最初の引数peripheralはペリフェラル・マネージャーを示します。2つ目の引数requestはセントラルからのリクエストを表すCBATTRequestクラスのインスタンスです。

CBATTRequestクラスは、プロパティのみでメソッドを持たないバリュー・オブジェクトです。プロパティは次の4つです。value以外、読み込みのみです。

  • CBCentral *central
    • リクエストを発生させたセントラルです。
  • CBCharacteristic *characteristic;
    • 対象となるキャラクタリスティクスです。
  • NSUInteger offset;
    • データのオフセットを表します。
  • NSData *value;
    • 値です

CBCentralクラスは、1つだけのプロパティ CFUUIDRef UUID のプロパティを持ちます。CFUUIDRefは128ビットのUUIDを扱う構造体のポインタです。CBUUIDクラスの + (CBUUID *)UUIDWithCFUUID:(CFUUIDRef)theUUID; クラスメソッドでCBUUIDのインスタンスに変換できます。このプロパティはセントラルの識別に使います。

リード・リクエストを受け取ったデリゲートは、セントラルが要求したデータを、CBATTRequestクラスのvalueプロパティに設定して返します。このために、まず対象となるキャラクタリスティクスが何かを調べます。これは、引数requestのcharacteristicプロパティのUUIDで判別できます。次のステップは、リード・リクエストのオフセット位置が、キャラクタリスティクスの値の範囲を超えていないことを確認します。

1
2
3
4
5
if (request.offset > myCharacteristic.value.length) {
[myPeripheralManager respondToRequest:request
withResult:CBATTErrorInvalidOffset];
return;
}

このオフセット値は、キャラクタリスティクスのデータが長くて、アトリビュート・プロトコルの1つのPDUに収まらない時に、複数のトランザクションに分割して読みだすときに使います。オフセット値が正しいと確認したのち、CBATTRequestのvalueプロパティに値を設定して、ペリフェラル・マネージャーのrespondToRequest:withResult:メソッドを呼び出します。Bluetooth LEの、リクエスト-レスポンスは1対1に対応しています。ですから、peripheralManager:didReceiveReadRequest:メソッドが呼び出されたら、対応するrespondToRequest:withResult:メソッドを、かならず1度だけ呼び出すようにします。

1
2
[myPeripheralManager respondToRequest:request withResult:CBATTErrorSuccess];
...

respondToRequest:withResult:メソッドは引数を2つ取ります。最初の引数requestは、デリゲートの呼び出しで渡されたCBATTRequestのインスタンスのvalueプロパティを設定したものです。2つ目の引数は、CBATTError列挙型の変数です。

もしも、ペリフェラルが公開しているキャラクタリスティクスにないキャラクタリスティクスを、リモートのセントラルが要求してきたなど、正常に処理ができない場合は、respondToRequest:withResult:にエラーコードを指定します。

書き込みリクエストへの応答

リモートのセントラルからローカルのペリフェラルへの書き込みの処理は、読み込みと同じです。セントラルが送信する、1つかそれ以上のキャラクタリスティクスへの書き込みリクエスを、ペリフェラル・マネージャーが受信すると、デリゲートのperipheralManager:didReceiveWriteRequests:メソッドを呼び出します。

peripheralManager:didReceiveWriteRequests:メソッドの引数は2つです。最初の引数は、ペリフェラル・マネージャーのインスタンスです。2つ目の引数はCBATTRequestのインスタンスの配列です。この引数のCBATTRequestのインスタンス1つ1つが、個別の書き込みリクエストです。

もしも2つ上の書き込みリクエストがきたときは、デリゲートは、それらのリクエストを1つのまとまりとして、アトミックに処理をします。一連の書き込みリクエストのうち1つが失敗したならば、一連の書き込み処理は実行されるべきではありません。

myCharacteristic.value = request.value;

書き込みリクエストの内容が正しいならば、対応するキャラクタリスティクスに値を書き込みます。このサンプル・コードにはありませんが、読み込み時と同じく、書き込みを実行する前に、オフセット値がキャラクタリスティクスの値の範囲を正しく示しているかを確認します。

読み込み時と同じく、リクエストとレスポンスは1対1に対応します。デリゲートのperipheralManager:didReceiveWriteRequests:メソッドが呼ばれたら、そのレスポンスとなるrespondToRequest:withResult:メソッドを、1回だけ呼び出します。

respondToRequest:withResult:メソッドの最初の引数は、respondToRequest:withResult:メソッドで渡されたCBATTRequestのインスタンスです。2つ目の引数はCBATTError列挙型の変数です。

1
2
[myPeripheralManager respondToRequest:[requests objectAtIndex:0]
withResult:CBATTErrorSuccess];
セントラルへの通知

リモートのセントラルは、ローカルのペリフェラル・マネージャーの1つあるいはそれ以上のキャラクタリスティクスをサブスクライブできます。サブスクライブされたキャラクタリスティクスの値が変更されると、ペリフェラル・マネージャーは、その更新値をリモートのセントラルに通知します。

接続しているセントラルがキャラクタリスティクスをサブスクライブを要求した時、ペリフェラル・マネージャーはデリゲートのperipheralManager:central:didSubscribeToCharacteristic:メソッドを呼び出します。

1
2
3
4
5
- (void)peripheralManager:(CBPeripheralManager *)peripheral
central:(CBCentral *)central
didSubscribeToCharacteristic:(CBCharacteristic *)characteristic {
NSLog(@"Central subscribed to characteristic %@", characteristic);
...

peripheralManager:central:didSubscribeToCharacteristic:メソッドは3つの引数、ペリフェラル・マネージャー、セントラル、そしてサブスクライブされるキャラクタリスティクスのインスタンスを取ります。iOSアプリケーションが、このキャラクタリスティクスがサブスクライブされていることを、覚えておきます。

iOSアプリケーションは、サブスクライブされているキャラクタリスティクスの値を更新するときに、ペリフェラル・マネージャーのupdateValue:forCharacteristic:onSubscribedCentrals: メソッドを呼び出します。

1
2
3
NSData *updatedValue = // fetch the characteristic's new value
BOOL didSendValue = [myPeripheralManager updateValue:updatedValue
forCharacteristic:characteristic onSubscribedCentrals:nil];

updateValue:forCharacteristic:onSubscribedCentrals:メソッドは3つの引数をとります。最初の引数は、更新された値を示すNSDataのインスタンス、2つ目の引数はキャラクタリスティクス、最後の引数は通知を送るCBCentralオブジェクトの配列です。

updateValue:forCharacteristic:onSubscribedCentrals:メソッドの最後のCBCentralの配列に、nilを指定すると、そのキャラクタリスティクスをサブスクライブする全てのセントラルに通知が送信されます。引数にCBCentralの配列を与えれば、その配列のセントラルのうち、そのキャラクタリスティクスをサブスクライブしているものに、通知が送信されます。配列の中に、そのキャラクタリスティクスをサブスクライブしていないセントラルがあっても、そのセントラルに通知が送信されることはありません。通知を送るセントラルの範囲を限定したい場合に使います。

updateValue:forCharacteristic:onSubscribedCentrals:メソッドの戻り値はBoolean型です。アップデートが送信できるならばYESが、送信キューが満杯で通知ができないならばNOが返されます。もしも戻り値がNOであれば、送信キューに空きができたときに、ペリフェラル・マネージャーはデリゲートのeripheralManagerIsReadyToUpdateSubscribers:メソッドを呼び出します。もしも望むならば、このメソッドが呼び出されたときに、再度、通知処理を行います。

この通知で送られるキャラクタリスティクスのデータ・サイズは、セントラル・マネージャーの場合と同じく、アトリビュート・プロトコルのATT_MTUで制約されます。もしもキャラクタリスティクスの値が、サイズ制約を超える場合は、それぞれのセントラルが、readValueForCharacteristic:メソッドを使ってオフセット値を指定して、そのキャラクタリスティクスのすべての値を読み出すべきです。

バックグラウンド処理

iOSアプリケーションはバックグラウンド実行に対応できます。しかし、iOSアプリケーションでは、電力やメモリなどのリソースの消費量が問題になります。そのため、iOSアプリケーションがフォアグラウンドかバックグラウンドにあるかで、無線を使うCore Bluetoothフレームワークの振る舞いが異なります。iOSアプリケーションのマルチタスキングの詳細は、iOSアプリケーション開発ガイドに掲載されたiOSアプリケーション プログラミングガイドの、アプリケーションの状態とマルチタスキング、の章を参照してください。

通常のiOSアプリケーションは、セントラルおよびペリフェラルいずれも、バックグラウンドでは動作が不可にされます。iOSアプリケーションのバックグラウンド・モードを設定してあれば、Bluetooth LE関連のイベントが発生すれば、対応するデリゲートのメソッドが呼び出されます。イベントの処理は、iOSアプリケーションが全ての処理を行う場合と、ユーザに通知表示を出すか否かだけをiOSに伝えて、あとの実際の通知処理はiOSに任せる場合の、2通りがあります。

フォアグラウンド状態のみiOSアプリケーション

バックグラウンド・モードをなにも指定しない通常のiOSアプリケーションは、バックグラウンド状態に入ると、短い実行時間ののちにサスペンド状態に移行します。サスペンド状態ではBluetooth関連のイベントは通知されず、システムがキューに貯めています。iOSアプリケーションがフォアグラウンド状態に戻った時に、キューにあるイベントが通知されます。ですから、もしもリモートとの接続が切断しても、それが通知されるのは、iOSアプリケーションがフォアグラウンドに戻った時です。

バックグラウンド・モードを指定しないセントラル・ロールのiOSアプリケーションは、フォアグラウンドでスキャンをしていても、バックグラウンドに入ると、スキャンは停止します。ペリフェラルの発見および切断のイベントも通知されません。

バックグラウンド・モードを指定しないペリフェラル・ロールのiOSアプリケーションは、バックグラウンド状態ではアドバタイズメントが停止されます。すでに接続が確立しているリモートのセントラルとの接続は、バックグラウンド状態になっても切れません。しかし、リモートのセントラルがダイナミックなキャラクタリスティクスの値にアクセスすると、エラーが返されます。

ユーザへのアラート通知

iOSアプリケーションが、バックグラウンド・モードを設定していなくて、バックグラウンド状態でBluetoothのイベントをアプリが処理できない場合でも、設定でiOSにBluetoothのイベントをユーザに通知させることはできます。

ユーザに通知できるのは、ローカルのiOSアプリケーションがセントラル・ロールのとき、リモートのペリフェラルとの接続が確立したこと、切断したこと、およびペリフェラルからのノーティフィケーションを受信したこと、の3つです。これらをiOSに通知させるかは、ペリフェラルに接続するときに呼び出す、セントラル・マネージャーのconnectPeripheral:options:メソッドのオプションで指定します。

connectPeripheral:options:メソッドのオプションには、NSDictionaryのインスタンスを指定します。辞書に使えるキーは以下の3つです。バリューはBoolean型変数をおさめたNSNumberのインスタンスです。キーを指定しなければ、NOを指定したのと同じで、ユーザ通知をしません。3つのうち2つのキーは、iOS6以降で利用できます。iOS5では、指定しても無視されます。

  • CBConnectPeripheralOptionNotifyOnConnectionKey (iOS6以降)
  • CBConnectPeripheralOptionNotifyOnDisconnectionKey
  • CBConnectPeripheralOptionNotifyOnNotificationKey (iOS6以降)

CBConnectPeripheralOptionNotifyOnConnectionKey はiOS6以降で有効です。バリューがYESのとき、iOSアプリケーションがサスペンドしている時にペリフェラルとの接続が確立すれば、iOSがユーザにアラート表示を行います。

CBConnectPeripheralOptionNotifyOnDisconnectionKey のバリューがYESのとき、iOSアプリケーションがサスペンドしている時にペリフェラルとの接続が切断すれば、iOSがユーザにアラート表示を行います。

CBConnectPeripheralOptionNotifyOnNotificationKey はiOS6以降で有効です。iOSアプリケーションがサスペンドしている時に、ペリフェラルからインディケーションがきたら、iOSはユーザにその内容を通知します。

バックグラウンド・モード

バックグラウンドでも、ペリフェラルからの通知や送られてくるセンサ・データの保存など、何かしらの処理が必要ならば、iOSアプリケーションのバックグラウンド・モードを指定します。バックグラウンド・モードは、iOSアプリケーションが任意の時間に任意の処理を行うためのものではなく、外部からのイベントを処理するためのものです。バックグラウンド・モードが指定されたiOSアプリケーションは、Bluetooth LEのイベントが発生するたびに、10秒間の実行時間を与えられて、サスペンド状態から実行状態になります。

バックグラウンド・モードは、iOSアプリケーションのInformation property list (Info.plist) ファイルにモードを宣言します。UIBackgroundModes keyに、セントラル・ロールならばbluetooth-centralを、ペリフェラル・ロールならばbluetooth-peripheralを設定します。もしもiOSアプリケーションが、セントラルとペリフェラルの両方の役割を持つならば、2つのバックグラウンド・モードを指定します。

Xcodeで
Info.plistファイルを開くと、プロパティ・リスト・エディタは生のキー名ではなく、人間がわかりやすい表記で表示します。生のキー名を表示したい時は、エディタ・ウィンドウのどこでもいいので、コントロール・キーを押しながらクリックをします。コンテキスト・メニューが表示されるので、その中の”Show Raw Keys/Values item”をチェックします。

セントラル・ロールでのバックグラウンド実行

iOSアプリケーションのInfo.plistファイルに、UIBackgroundModesキーにbluetooth-centralを設定すれば、セントラル・ロールのiOSアプリケーションはバックグラウンドで実行されます。バックグラウンド状態でペリフェラルのスキャンができます。またiOSは、ペリフェラルの発見と接続完了、読み書きと切断のイベントで、バックグラウンドでも、iOSアプリケーションをスタンドバイ状態から起こして、CBCentralManagerDelegateプロトコルの該当するメソッドを呼び出します。

ただし、iOSアプリケーションがフォアグラウンド状態とバックグラウンド状態のときでは、電力消費量を抑えるために、Bluetooth LEの振る舞いが異なります。Bluetooth LEの通信接続自体はフォアグラウンド状態の時と同じです。

バックグラウンド状態では、重複するペリフェラルのアドバタイジングを都度知らせるスキャン・オプションCBCentralManagerScanOptionAllowDuplicatesKeyが無視され、ペリフェラルの発見は1度だけ通知されます。また、定常的に電力を消費するスキャンは、ペリフェラルをスキャンする全てのiOSアプリケーションがバックグラウンド状態であれば、12分に1回程度と、低頻度になります。このため、バックグラウンド状態ではペリフェラルの発見に、時間がかかります。フォアグラウンド状態のiOSアプリケーションがスキャンをしていれば、バックグラウンド状態のiOSアプリケーションにも、フォアグラウンド状態と同じスキャン周期が与えられます。

ペリフェラル・ロールでのバックグラウンド実行

iOSアプリケーションのInfo.plistファイルに、UIBackgroundModesキーにbluetooth-peripheralを設定すれば、ペリフェラル・ロールのiOSアプリケーションはバックグラウンドで実行されます。バックグラウンド状態でアドバタイズメントができます。またiOSは、セントラルからの読み書きやサブスクライブのアクセスがあると、iOSアプリケーションをスタンドバイ状態から起こして、CBPeripheralManagerDelegateプロトコルの該当するメソッドを呼び出します。

バックグラウンド状態でのアドバタイズメントは、フォアグラウンド状態のときとは、振る舞いが異なります。iOSはアドバタイズメント・パケットの長さを可能な限り短くすることで、電波の送信時間を短くして、電池消費量を最小にしようとします。

アドバタイズメント・データに指定したCBAdvertisementDataLocalNameKeyキーが無視されて、ペリフェラルのローカル・ネームはアドバタイジングされません。CBAdvertisementDataServiceUUIDsKeyキーで指定したサービスUUIDsは、アドバタイズメント・パケットで送信されません。リモートのセントラルが、スキャン・リクエストすることで、サービスUUIDsが取得できます。また、アドバタイズメントしているiOSアプリケーションが全てバックグラウンド状態のときは、アドバタイジングの周期自体が下がります。フォアグラウンド状態のiOSアプリケーションがアドバタイジングしていれば、バックグラウンド状態のiOSアプリケーションにも、フォアグラウンド状態と同じアドバタイズメントの周期が与えられます。

バックグラウンド・モードのベストプラクティス

iOSアプリケーションは、電池消費量を特に気にします。個別の実装ごとに、こうなればこうなると考えていくのは大変です。バックグラウンド・モードの使いかたの指針をいくつか示します。

  • Bluetoothの利用をユーザが選択できるインタフェース設計
  • 目的に合わせたバックグラウンド・モードの利用
  • バックグラウンドでの初利を最小の時間に抑える

iOSアプリケーションは、Bluetooth LEを利用する場面では、セッションベースのインタフェースを提供します。例えばスキャンがいつ開始して、いつ終了するかが、画面の表示遷移とひもづけられていれば、ユーザから見てなにをしているのかが明確になります。また、バックグラウンド・モードでデータ同期する/しないなど、Bluetooth LEを利用する機能を、ユーザ設定画面で提供することもよいでしょう。

Bluetooth LEのバックグラウンド・モードは、それを使う必要があるiOSアプリケーションが使うべきものです。Bluetooth LEを必要としないのに、バックグラウンドでのiOSアプリケーションの動作を得るためだけに、このバックグラウンド・モードを使うべきではありません。

また、Bluetooth LEのイベントごとに、iOSアプリケーションには10秒の実行時間が与えられます。この10秒をすべて使うのではなく、必要なタスク処理が完了すれば、iOSに処理を戻して、iOSアプリケーションの実行時間を最小にします。

Core Bluetoothフレームワークのベスト・プラクティス

Core Bluetoothフレームワークは、iOSアプリケーションに、Bluetooth LEの通信の詳細を隠蔽して、抽象化された振る舞いを提供します。これによりiOSアプリケーション開発者は、Bluetooth LEの通信規格を理解しなくても、求める振る舞いを実装できます。

しかし、Bluetooth LEを利用する限り、必ずリモートのペリフェラルまたはセントラルが振る舞いに関わります。そして、ローカルとリモートのデバイスの間を電波がつなぐのです。高度に抽象化されても、なおiOSデバイス単体で完結する通常のiOSアプリケーションにはない配慮も必要です。ここでは、Core Bluetoothフレームワークを使うノウハウを述べます。

スキャンは必要最小限に

Bluetooth LEで電力を消費するのは、スキャンです。いつくるかタイミングが分からない、8桁も違う受信信号電力を検出するため、高周波回路が最も電力を消費する状態です。次に電力を消費するのが、アドバタイズメントです。無線通信は、超低消費電力無線通信の名称が示すとおり、高周波回路の消費電力は少量です。ただし、イベントを処理するために、iOSアプリケーションが動作すれば、その分の電力消費が生じます。したがって、スキャンを最小に、アドバタイズメントは利用時間をなるべく少なくするように、注意します。

リモートのペリフェラルの発見のために、セントラル・マネージャーのscanForPeripheralsWithServices:options:メソッドを呼び出せば、スキャンが開始されます。このスキャンはタイムアウトしません。ペリフェラルを発見したならば、セントラル・マネージャーのstopScanメソッドを呼び出して、iOSにスキャンの停止を指示します。

stopScanメソッドを呼び出しても、直ちにそのiOSデバイスのスキャンが停止するとは限りません。Bluetooth LEは複数のiOSアプリケーションで利用されます。そのiOSアプリケーションがstopScanメソッドを呼び出しても、他のiOSアプリケーションがスキャンを実行していれば、そのiOSデバイスのスキャンは実行され続けるでしょう。

iOSアプリケーションがバックグラウンド状態になったとき、バックグラウンド・モードが指定されていない場合は、スキャンは停止します。<TBD物理的にスキャンが停止するの? また、フォアグラウンドになったら再開するの? /> バックグラウンド・モードにbluetooth-centralを指定していれば、スキャンは継続して実行されますが、ペリフェラルを見つける周期はフォアグラウンド状態のときよりも長くなります。

重複するアドバタイズメント・パケットの検出は最小に

セントラルに接続していないペリフェラルは、周囲のセントラルに存在を伝えるために、アドバタイズメント・パケットを送信し続けます。

セントラル・マネージャーのscanForPeripheralsWithServices:options:メソッドは、アドバタイズメント・パケットを受信してペリフェラルを発見した時に、デリゲートのcentralManager:didDiscoverPeripheral:advertisementData:RSSI:メソッドを呼び出します。また、同じペリフェラルでも、アドバタイズメント・パケットのデータが、以前に受信したデータと異なる場合にも、このデリゲートを呼び出します。

アドバタイズメント・パケットを受信した都度、デリゲートを呼び出させたいときは、scanForPeripheralsWithServices:options:メソッドのオプションで、CBCentralManagerScanOptionAllowDuplicatesKeyのバリューをYESに設定します。これは、受信信号強度をモニタし続けて、ペリフェラルが十分近くに来た時に初めて接続させたいときに、使ったりします。しかし、連続してスキャンをし続けるため、バッテリー消費量が大きくなります。必要な場合にのみ使用します。

サービスの検索を最小に

たいてい、ペリフェラルには数多くのサービスがあり、iOSアプリケーションが利用するのは、その一部分です。ペリフェラルにどのようなサービスおよびキャラクタリスティクスがあるかを検索すると、その検索データのやり取りのために、無線通信の時間と処理時間がかかります。

iOSアプリケーションの設計段階で、ユースケースに求められるペリフェラルのサービスとキャラクタリスティクスは決まります。ですから、検索は利用するものだけに限定することを勧めます。サービスを検索するCBPeripheralクラスのdiscoverServices:メソッドには、検索したいサービスのUUIDsを引数に指定できます。同様に、CBperipheralクラスのscanForPeripheralsWithServices:options:メソッドも、検索したいキャラクタリスティクスのUUIDsを引数に指定できます。

1
[peripheral discoverServices:@[firstServiceUUID, secondServiceUUID]];

サブスクライブと読み出しの使いかた

リモートのペリフェラルのキャラクタリスティクスの値が変化する場合、その値の読み出し方法には、ポーリングとサブスクライブの2つの方法があります。ポーリングは、ローカルのセントラルから一定期間でreadValueForCharacteristic:メソッドを呼び出して、明示的にキャラクタリスティクスの値を読み出す方法です。サブスクライブは、setNotifyValue:forCharacteristic:を1度呼び出しておけば、リモートのキャラクタリスティクスの値が変更される都度、リモートのペリフェラルからセントラルに通知される方法です。

キャラクタリスティクスの値の変化をモニタするには、サブスクライブを使います。ただし、そのキャラクタリスティクスのpropertyプロパティをみて、インディケーションまたはノーティフィケーションのすくなくとも1つをサポートしていなければ、サブスクライブはできません。

ただし、あまりに頻繁に値が変化するキャラクタリスティクスは、ポーリングを使ったほうが消費電力を抑えられるかもしれません。

ペリフェラルの切断

もうペリフェラルを使わないならば、接続を切断すれば無線をより使わなくなり、電力消費量を抑えられるでしょう。

キャラクタリスティクスがノーティフィケーションを停止した場合は、もう値の更新を通知してくることはありません。これは、キャラクタリスティクスのisNotifyingプロパティがNOになっていることで確認できます。サブスクライブしている全てのキャラクタリスティクスのノーティフィケーションが停止したならば、もうペリフェラルと接続しつづける必要がないので、切断します。

またペリフェラルから必要なすべてのデータを読みだした場合も、接続し続ける必要はないので、切断します。
<!–
この説、なにが言いたいんだろう。

どっちの場合でも、持ってるだろうサブスクライブををキャンセルしろ、
ペリフェラルから切断する。

キャラクタリスティクスの値のサブスクライブは、
setNotifyValue:forCharacteristic: methodの最初のパラメータをNO
ペリフェラルへの接続をキャンセルできる、cancelPeripheralConnection: method of the CBCentralManager class,

1
[myCentralManager cancelPeripheralConnection:peripheral];

–>

ペリフェラルの切断には、CBPeripheralクラスのcancelPeripheralConnection:メソッドを呼び出します。このメソッドは、処理をブロックすることなく直ちに返ってきます。しかし、ペリフェラルとの実際の切断処理は、iOSがキャッシュして、後に実行されます。このため、ペリフェラルとの切断がいつ完了するかは、iOSアプリケーションからはわかりません。

ペリフェラルへの再接続

ペリフェラルに接続する方法は、今までに述べたペリフェラルを発見して接続する以外に、過去に一度接続したことがあるペリフェラル、また現在iOSデバイスに接続しているペリフェラルに接続する方法があります。

ペリフェラルに接続した時、iOSはそのペリフェラルをそれぞれ識別するUUIDを生成します。このUUIDを保存しておくと、あとでペリフェラルに再接続したいときに、セントラル・マネージャーのretrievePeripherals:メソッドを呼び出す時のペリフェラルの指定に使えます。

[myCentralManager retrievePeripherals:savedPeripheralUUIDs];

iOSデバイスが過去に接続したことがあるペリフェラルであれば、セントラル・マネージャーのretrievePeripherals:メソッドに、問い合わせたいペリフェラルのUUIDの配列を与えて呼び出します。UUIDはCFUUIDRefのインスタンスで表します。CBUUIDはBluetooth LEのサービスやキャラクタリスティクスの識別に使います。CBUUIDクラス自体がUUIDを表すのですが、これはBluetoothのために作られたクラスなので、ペリフェラルの識別のUUIDには、Bluetoothに関係がないCFUUIDRefが使われます。

セントラル・マネージャーは、指定されたUUIDの配列の中から、過去に接続したことのあるペリフェラルのUUIDを見つけます。CBCentralManagerDelegateプロトコルのcentralManager:didRetrievePeripherals:メソッドで、発見したペリフェラルに対応するCBPeripheralのインスタンスの配列を返します。もしも該当するペリフェラルが1つもなかった場合は、空の配列を返します。

取得したペリフェラルの配列のなかから、画面に表示してユーザが選択する、あるいはiOSアプリケーション内部で判定して、接続したいペリフェラルを選択します。ペリフェラルへの接続には、スキャンの後に接続した時と同じく、セントラル・マネージャーのconnectPeripheral:options:メソッドを呼び出します。このとき、そのペリフェラルがiOSデバイスとすでに接続していれば、セントラル・マネージャーはデリゲートのcentralManager:didConnectPeripheral:メソッドを呼び出します。

centralManager:didConnectPeripheral:メソッドを呼び出しても、ペリフェラルが周囲にいなければ、接続はできません。また、Bluetooth LEデバイスには、プライバシーを保護するために、デバイスの特定を防ぐ、ランダム・アドレスという仕組みがあります。これは、リンク層のアドレスを一定周期で変更します。ランダム・アドレスを使うペリフェラルは、たとえ周囲にあったとしても、前回接続した時とアドレスが異なるので、再接続ができません。この場合は、再度スキャンをしてペリフェラルの発見から、接続をやり直します。

接続しているペリフェラルのリストを取得する

ペリフェラルに再接続する残る1つの方法は、セントラル・マネージャーのretrieveConnectedPeripheralsメソッドを呼び出して、現在iOSデバイスに接続しているペリフェラルを取得することです。

retrieveConnectedPeripheralsメソッドを呼び出すと、
セントラル・マネージャーは、いまiOSデバイスに接続している全てのペリフェラルを、デリゲートのcentralManager:didRetrieveConnectedPeripherals:メソッドで通知します。

centralManager:didRetrieveConnectedPeripherals:メソッドの2つ目の引数はCBPeripheralのインスタンスの配列です。もしもiOSデバイスに接続しているペリフェラルがない時は、空の配列が渡されます。

iOSデバイスとペリフェラルとのBluetooth LEの接続が確立しているときでも、iOSアプリケーションとペリフェラルとの接続は、ペリフェラルを発見した時と同じ手順です。セントラル・マネージャーのconnectPeripheral:options:メソッドを呼び出して接続を行います。iOSアプリケーションとの接続が確立すれば、セントラル・マネージャーはデリゲートのcentralManager:didConnectPeripheral:メソッドを呼び出します。

アドバタイジング・データの考慮

iOSアプリケーションがペリフェラル・ロールのとき、そのアドバタイジング・データは、ペリフェラル・マネージャーのstartAdvertising:メソッドに渡す辞書で指定できます。しかし、アドバタイズメント・パケットのペイロードにはサイズ制約があります。またバックグラウンド状態では、iOSがパケット・サイズを最小にしようとします。このため、指定したアドバタイズメント・データと、実際に送信されるアドバタイジング・データの対応を知っておくことが大切になります。

アドバタイズメント・パケットは、ペリフェラルに関する情報をブロードキャストするのに、使います。そのアドバタイジング・データは、ペリフェラルのローカル名およびサービスのUUIDsを入れられます。指定できるキーは:

  • CBAdvertisementDataLocalNameKey
  • CBAdvertisementDataServiceUUIDsKey.

これ以外のキーを指定すると、エラーとなります。

アドバタイジング・データは、iOSアプリケーションがフォアグラウンド状態のとき、28バイトまでの制限があります。これはBluetooth LEの、パケットの最大サイズによる制約です。この28バイトは、キーごとに必要な2バイトのヘッダと、そのバイト・データの合計値が、それ以下になることを意味します。

もしも指定したデータが28バイトを超える場合は、アクティブ・スキャンでペリフェラルが返すパケットの空き領域10バイトが使われます。ただし、この領域を使えるのは、ローカルネームだけです。 そのため、アクティブ・スキャンをしない限りローカルネームを見つけられません。

iOSアプリケーションがバックグラウンド状態にあると、全てのサービスUUIDsは、オーバフロー領域に置かれます。またローカルネームはアドバタイジングされません。

これらの制約から、アドバタイジングするサービスUUIDは、プライマリ・サービスを特定するものだけにしておくことを勧めます。

  • ユーザにアドバタイズメントするか決めさせる

トラブルの原因切り分けと対応

Appcessoryという単語が示す通り、Bluetooth LEデバイスとiOSアプリケーションそしてネットワークの先にあるサービスが連携して初めて、魅力あるBluetooth LEデバイスという製品になります。しかし、意図せぬ振る舞いが、開発中また販売後に起きるかもしれません。ここでは、iOSアプリケーションとBluetooth LEデバイスが意図しない振る舞いをすることを、トラブルと呼びます。

トラブルが発生した場合は、原因の切り分けが必要です。そのためには、トラブルを再現する方法や発生条件を明らかにすることが必要です。これらのタスクは、ユーザから情報を集めるような対人タスクと、与えられた条件から現象を論理的に分析する純粋な技術タスクに分けられます。具体的なトラブルは予測困難ですが、発生しうるトラブルの種類を列挙して、タスクの割り振り役および分野ごとの担当者などを、開発チームで事前に決めておくことが重要です。

トラブルの原因が設計によるものであれば、それは、iOSアプリケーション単体によるもの、Bluetooth LEデバイス単体によるもの、および両者の振る舞いの組み合わせによるもの、の3通りです。また、それが分析できるのはBluetooth LEデバイスの設計者か、iOSアプリケーション開発者のいずれかです。

ほとんどのトラブルは、iOSアプリケーション開発者の初歩的なミスが原因です。例えば、CBPeripheralのインスタンスをリテインし忘れたために接続が解除された、のようなケアレスミスによるものが多いです。開発過程での、ケアレスミスによるトラブルで発生するやりとりを防止するには、Bluetooth LEデバイス開発側が、iOSアプリケーションのCore Bluetoothフレームワークを使う部分まで含めて、開発を担当することが有効です。

iOSアプリケーションとBluetooth LEデバイスの振る舞いの組み合わせがトラブルの原因の場合は、両者の振る舞いをログを取りながら突き合わせるか、あるいはBluetooth LEの通信パケットをロギングして解析します。いずれの場合も、iOSとファームウェアおよび通信の知識が不可欠になるため、領域ごとの担当者が個別に担当するのではなく、同じ場所と同じ時間を共有して対処にあたるように、事前に決めておくことが重要です。

使用しているBluetooth LEデバイスが、市販品とその付属ライブラリを利用しているのか、または独自に設計しているのかで、対処が異なります。市販品の場合は、ライブラリのソースコードが公開されているならば、ソースコードを読むことが原因を見つける早道です。もしもソースコードが公開されていないならば、Bluetooth LEの通信パケットをロギングして解析するほかありません。独自に設計したデバイスを使用しているならば、ファームウェアのソースコードもつきあわせて、開発者間で振る舞いを1つ1つ確認していくのが、早道です。

開発環境とターゲット

4S以降、環境iOS5以降
Xcode

参考情報源

https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/AboutCoreBluetooth/Introduction.html

https://devforums.apple.com/community/ios/core/cbt

https://lists.apple.com/mailman/listinfo/bluetooth-dev

CoreBluetoothフレームワーク

セントラルとペリフェラル
iOS5とiOS6

クラス構造

CBCentralManager

雑渡した使いかた、引数の意味。
セントラル
デバイスの発見、接続
サービスおよびキャラクタリスティクスの発見

排他制御ってどうなっている。
本体の二つのアプリから同時に接続出来ちゃったりするのかしら。

UUIDの意味

CBPeripheralManager

ペリフェラル

使いかた

オブザーバ

アドバタイジング・パケット。受信。
UUID、Duplicate key。

バックグラウンド

消費電力、頻度。BGで一二分に一回とか。
他のアプリが動いていると、とか。

デバイスの管理

実際の開発例

センサータグで
オリジナルの機器、スニッフィング

123456789012345678901234567890123456789012345678





























1===============================================

Bluetotoh LEに対応するiOSデバイスとOSのバージョン

Bluetooth LEに対応するには、ハードウェアとOSがそれぞれ対応しなければなりません。

Bluetooth LEはBluetooth4の規格の一部です。スマートフォンのハードウェアの仕様に、Bluetooth4対応と書かれていれば、それはBluetooth LEにも対応しています。iOSデバイスは、2011年10月に発売されたiPhone4S以降の全てのデバイスがBluetooth4に対応しています。2013年8月時点で、Bluetooth4に対応するiOSデバイスは、iPhone4S、iPhone5, 第5世代iPod touch、第3および第4世代iPad、そしてiPad miniです。

Bluetooth LEに対応するOSのバージョンは、iOS5およびiOS6です。Core Bluetoothフレームワークは、iOS5以降のSDKに含まれています。初めてBluetooth LEをサポートしたiOS5はセントラルの機能を提供しています。次のiOS6では、セントラルに加えてペリフェラルの機能にも対応しました。セントラルおよびペリフェラルについては次の節で述べます。

iOS5およびiOS6は、iPhone3GSおよびiPhone4などの、ハードウェアがBluetooth4に対応していないiOSデバイスにも対応しています。Core Bluetoothフレームワークは、アプリケーションが実行されたデバイスがBluetooth LEに対応しているかいなかを、デリゲートを通してアプリケーションに知らせます。

Bluetooth LEを使うアプリケーションの振る舞いが、機種により異ならないかは、大きな関心事です。もしも振る舞いが異なるならば、どのiOSデバイスでどのように異なるのか、またその理由を理解して、テスト項目に入れなければなりません。筆者の知る範囲では、iOSデバイスの機種間で振る舞いが異なることはありません。

デバイスごとの差異が生じるうる要素には、アンテナ設計、無線通信の半導体およびその内部で動作するファームウェア、そしてiOS側の通信制御プログラムがあります。

アンテナは機種ごとに異なります。アンテナ自体の利得および指向性が異なるかもしれません。Bluetooth LEで通信をするだけであれば、利得の違いは通信可能距離の大小として見えます。検出される電波強度の絶対値が異なりますから、電波強度を用いる応用例では、その違いが振る舞いを変えるかもしれません。例えば、電波強度による近接検出ならば、近接と判断する距離が機種により異なってくるでしょう。

無線通信の半導体は、Bluetooth規格に従い実装されるので、半導体による機能の違いはないはずです。またiFixitが報告しているiPhoneの内部構成をみると、無線通信の半導体は、iPhone4SとiPad3はBroadcom社のBCM4330、iPhone5とiPad miniとiPod touch 5th Genは、同じくBroadcom社のBCM4334を採用しています。BCM4330からBCM4334の変更点は、半導体の製造プロセスが65nmから40nm LPに変更され、受信動作時のピーク電流が68mAから36mAに半減したことです。ですから、ただし、受信動作による電池消費量は、機種によって2倍違うでしょうが、ハードウェアの機能の違いはないでしょう。

iOS側の通信制御プログラムは、iOSのメジャー番号が変わると異なることがあります。またマイナーバージョンで、バグの修正や動作をより安定にする変更が入ります。動作保証対象となるiOSのバージョンごとに、動作の確認が必要です。