Developer's Blog

【連載】Bluetooth LE (6) iOS 7 での CoreBluetooth の変化

こんにちは。共同開発部 開発担当の図子です。

Bluetooth LE の連載が今回で6回目となりました。今回は iOS 7 で追加された機能や API の変化をあげていきたいと思います。

iOS 5 から iOS 6 へのバージョンアップでは第3回で紹介した「iOS デバイスを BLE 機器側にする機能」が追加されました。これは当時としては非常に大きな変化で、それまでは専用のハードウェアを用意しなければいけなかったのを iOS デバイスと iOS エンジニアのスキルセットで機器側を開発できるものでした。

iOS 6 から iOS 7 へのバージョンアップは個人的な見解では先に挙げたような大きな変化はありません。どちらかというと正常進化といえると思います。

機能的な変化

iOS 6 で導入されたキャッシュ機構の拡張

今までも

  • Service
  • Characteristic

はキャッシュされていましたが iOS 7 ではさらに

  • Characteristic Value
  • Descriptor

もキャッシュされるようになりました。これによりいっそうのスピードの向上とバッテリーライフの向上が期待できます。Characteristic Value のキャッシュは最後に取得した Characteristic のデータをキャッシュされます。

データ転送速度の向上

BLE 機器側が対応していれば 20 %ほどデータの送信速度が向上しているそうです。

リストア機構の登場

バックグラウンド動作時にアプリが終了しても OS 側が代わりに通信してくれ、必要に応じてアプリを復帰させてくれるようになりました。主に以下の実装を行っていれば状態を復元してくれます。

  • CBCentralManager の生成に – (id)initWithDelegate:(id<CBCentralManagerDelegate>)delegate queue:(dispatch_queue_t)queue options:(NSDictionary *)options を使いオプションとして Identifier を渡しておく。
  • – (void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary *)dict が呼ばれたときに dictionary から必要な情報を取り出して状態管理を行う

これらの機構は長時間 BLE の通信が必要なアプリではありがたい機能になります。

API の変化

CBCentralManager のイニシャライザ追加

先ほど紹介したようにリストアのために新しいイニシャライザが追加されました。

– (id)initWithDelegate:(id<CBCentralManagerDelegate>)delegate queue:(dispatch_queue_t)queue options:(NSDictionary *)options

options ディクショナリに入れるキーと値は以下のようになっています。

  • CBCentralManagerOptionRestoreIdentifierKey
    • iOS 7 から追加された Restore 機能のための Identifier を渡すための Dictionary Key
  • CBCentralManagerOptionShowPowerAlertKey
    • CBCentralManager の初期化時に Bluetooth が Off になっていた場合にアラートを出すかどうか。

CBCentralManager の scan オプション追加

scanForPeripheralsWithServices:options: に渡す Key が増えました。CBCentralManagerScanOptionSolicitedServiceUUIDsKey が追加され配列で渡した CBUUID の Service を探すようですが、scanForPeripheralsWithServices:options: に渡す sercices 配列との違いがまだ私にはわかっていません。

Retrieve メソッド群の変更と簡略化

iOS 6 まで Retrieve には

  • retrieveConnectedPeripherals
  • retrievePeripherals:

を使っていました。これらのメソッドは戻り値が void であり、結果は Delegate メソッドとして非同期に返ってきていました。iOS 7 では

  • retrievePeripheralsWithIdentifiers:
  • retrieveConnectedPeripheralsWithServices:

という新しいメソッドに変更になりました。引数が変わったのは見た目にも明らかですが1番大きなのは戻り値が void から NSArray に代わり Delegate メソッドによる非同期ではなくなり同期的になりました。コードを書く側としては非同期より同期の方がコードもシンプルになり非常に書きやすくなりました。

CBCentralManagerDelegate

リストア用のデリゲートメソッド追加

– (void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary *)dict

OS が Restore した際に呼ばれるデリゲートメソッドです。各種 Restore 情報は dict から取得できます。

  • CBCentralManagerRestoredStatePeripheralsKey
    • アプリ終了時に繋がっていたもしくは繋ごうとしていた CBPeripheral のインスタンスの配列へアクセスするためのキー。可能な場合にはディスカバー済みの Service や Characteristics 等も復元される。
  • CBCentralManagerRestoredStateScanServicesKey
    • アプリ終了時に Scan しようとしていた Service UUID の配列へアクセスするためのキー。
  • CBCentralManagerRestoredStateScanOptionsKey
    • アプリ終了時に Scan するときに渡していた Option へアクセスするためのキー。

Advertise に乗っているデータの取得キー

  • CBAdvertisementDataIsConnectable
  • CBAdvertisementDataSolicitedServiceUUIDsKey

上記2点が追加されています。CBAdvertisementDataIsConnectable は接続可能かの情報が NSNumber で格納されている。CBAdvertisementDataSolicitedServiceUUIDsKey は CBUUID の配列が格納されています。

CBPeripheral

UUID にかわり identifier プロパティが追加

UUID プロパティが Deprecated となりました。かわりに NSUUID を返す identifier プロパティが追加されました。

状態を取得するプロパティが使いやすくなった

isConnected プロパティが Deprecated。かわりにより詳細な状態がわかる state プロパティが追加。

BOOL を返す isConnected が Deprecated となり、かわりにより下記のような詳細な状態がわかる state プロパティが新設されました。

  • 切断状態
  • 接続中
  • 接続済み

これまでは上記3つの状態を把握するためには独自に状態管理を行う必要があったためうれしい変更です。

まとめ

このように Core Bluetooth は OS のバージョンアップとともに進化してきました。登場当初はドキュメントもなかったり動作も不安定な印象がありましたが着実に進化し安定してきています。もし、これから Core Bluetooth を使ったアプリを開発する場合は安定性の面や今回紹介したような新機能を活用できるという面も含めて iOS 7 用アプリとして開発するのが良いのではないでしょうか? 

フェンリルのオフィシャル Twitter アカウントでは、フェンリルプロダクトの最新情報などをつぶやいています。よろしければフォローしてください!

Copyright © 2019 Fenrir Inc. All rights reserved.