Core Bluetoothを使ったアプリの実装
■ CBCentralManager
CBCentralManagerは、Bluetooth LEに対応するデバイスの検索や接続処理などを行うコンポーネントです。デバイスの検索処理の結果や接続状態の変化などは、CBCentralManagerDelegateプロトコルに適合するデリゲートでハンドルすることになります。
CBCentralManagerを作成する部分のコードです。
centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
- - PR -
initWithDelegate:queue:メソッドでデリゲートを指定して生成しています。queueパラメータは、デリゲートメソッドが呼び出されるスレッドをdispatch queueで指定します。nilを指定した場合、メインスレッドのdispatch queueが自動的に選択されます。
■ Bluetooth LE対応デバイスの探索
iOSデバイスはBluetooth Smart Readyデバイス側なので、アドバタイズしているデバイスを探索することになります。その際はCBCentralManagerのscanForPeripheralsWithServices:options:メソッドを利用します。以下は、CBCentralMangerでデバイスを探索する部分のコードです。
// 探索対象のデバイスが持つサービスを指定
NSArray *services = [NSArray arrayWithObjects:[CBUUID UUIDWithString:kUUIDServiceImmediateAlert],
[CBUUID UUIDWithString:kUUIDServiceBatteryService], nil];
// 単一デバイスの発見イベントを重複して発行させない
NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO]
forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
// デバイスの探索を開始
[centralManager scanForPeripheralsWithServices:services options:options];
scanForPeripheralsWithServices:options:メソッドの最初のパラメータは、探索対象のデバイスを絞り込むためのものです。このパラメータで渡したサービスに対応しているデバイスのみが探索対象です。
GATTプロファイルの仕様では、各サービスやキャラクタリスティックなどを識別するためにUUIDが割り当てられており、サービスの指定はUUIDを表すCBUUIDクラスのインスタンスの配列によって行います。このパラメータにnilをセットすることにより探索対象を制限しないようにできますが、この方法は推奨されていません。
今回のサンプルアプリでは、Immediate AlertサービスのUUIDである「1802」と、Battery ServiceサービスのUUIDである「180F」を探索対象サービスのUUIDとして指定しています。
optionsパラメータには、NSDictionaryにデバイス探索時のオプションをセットして渡しています。このパラメータで、CBCentralManagerScanOptionAllowDuplicatesKeyを「YES」に設定した場合、探索対象のサービスをアドバタイズしているデバイスが見つかるたびにデバイスの発見をCBCentralMangerのデリゲートに通知します。「NO」に設定した場合は、探索対象のサービスをアドバタイズしているデバイスが見つかると、CBCentralMangerのデリゲートに通知します。複数の探索対象サービスで同一のデバイスを発見した場合は、CBCentralMangerのデリゲートへの通知が1回にまとめられます。
このサンプルでは、Immediate AlertサービスとBattery Serviceサービスが同一デバイスに搭載されていることを前提としていますので、CBCentralManagerScanOptionAllowDuplicatesKeyをNOに設定して、同一デバイス発見の通知が1回のみになるようにしています。
■ デバイスの発見と接続
デバイスが発見されると、CBCentralManagerDelegateのcentralManager:didDiscoverPeripheral:advertisementData:RSSI:メソッドが呼び出されます。以下は、メソッド内の処理です。
- (void)centralManager:(CBCentralManager *)central
didDiscoverPeripheral:(CBPeripheral *)peripheral
advertisementData:(NSDictionary *)advertisementData
RSSI:(NSNumber *)RSSI
{
targetPeripheral = peripheral;
peripheral.delegate = self;
// 発見されたデバイスに接続
if (!peripheral.isConnected)
{
[centralManager connectPeripheral:peripheral options:nil];
}
}
CBPeripheralはデバイスを表すクラスです。peripheralパラメータには、発見されたデバイスに対応するCBPeripheralのインスタンスがセットされています。デバイス間で通信を行う際は、CBPeripheralのインスタンスを利用するので、参照をクラスの変数に格納しておきます。
また、CBPeripheralの処理結果や状態の変化時は、CBPeripheralDelegateプロトコルに適合したデリゲートでハンドルすることになるので、CBPeripheralのインスタンスにデリゲートを指定しておきます。
そのほか、advertisementDataパラメータは発見されたデバイスの情報がNSDictionary型で格納されており、RSSIには信号強度がNSNumber型で格納されています。
デバイスが発見された場合は続けて接続処理を行います。発見されたデバイスとの接続処理は、CBCentralManagerのconnectPeripheral:options:メソッドで行います。
■ デバイスの接続とサービスの探索
デバイスの接続が完了するとCBCentralManagerDelegateのcentralManager:didConnectPeripheral:メソッドが呼び出されます。また、デバイスの接続に失敗した場合は、CBCentralManagerDelegateのcentralManager:didFailToConnectPeripheral:error:メソッドが呼び出されます。以下は、centralManager:didConnectPeripheral:メソッド内の処理です。
- (void)centralManager:(CBCentralManager *)central
didConnectPeripheral:(CBPeripheral *)peripheral
{
// 外部デバイスとの接続完了を通知
[self.delegate peripheralManagerDidConnectPeripheral:self];
// 探索するサービスを指定
NSArray *services = [NSArray arrayWithObjects:[CBUUID UUIDWithString:kUUIDServiceImmediateAlert],
[CBUUID UUIDWithString:kUUIDServiceBatteryService], nil];
// サービスの探索を開始
[peripheral discoverServices:services];
}
必要があればUIの更新処理を行い、次に、接続したデバイスに搭載されているサービスの探索を行います。サービスの探索は、CBPeripheralのdiscoverServicesメソッドで行います。パラメータで渡しているサービスのUUIDの配列は、CBCentralManagerのscanForPeripheralsWithServices:options:メソッドの場合と同様に探索するサービスを指定するものです。
ここでも、サービスを指定せずnilをセットできますが、こちらもまた非推奨です。これはキャラクタリスティックやディスクリプタの探索時も同様です。
■ サービスの発見とキャラクタリスティックの探索
サービスが発見されるとCBPeripheralDelegateのperipheral:didDiscoverServices:が呼び出されます。
- (void)peripheral:(CBPeripheral *)peripheral
didDiscoverServices:(NSError *)error
{
if (error)
{
NSLog(@"didDiscoverServices error: %@", error.localizedDescription);
return;
}
if (peripheral.services.count == 0)
{
NSLog(@"didDiscoverServices no services");
return;
}
for (CBService *service in peripheral.services)
{
if ([service.UUID isEqual:[CBUUID UUIDWithString:kUUIDServiceImmediateAlert]])
{
// Immediate Alertサービスを発見した場合、Alert Levelキャラクタリスティックの探索を開始
[peripheral discoverCharacteristics:[NSArray arrayWithObjects:[CBUUID UUIDWithString:kUUIDCharacteristicsAlertLevel], nil] forService:service];
}
else if ([service.UUID isEqual:[CBUUID UUIDWithString:kUUIDServiceBatteryService]])
{
// Battery Serviceサービスを発見した場合、Battery Levelキャラクタリスティックの探索を開始
[peripheral discoverCharacteristics:[NSArray arrayWithObjects:[CBUUID UUIDWithString:kUUIDCharacteristicsBatteryLevel], nil] forService:service];
}
}
}
サービス探索時にエラーがあった場合はerrorパラメータにエラーがセットされます。
CBServiceはサービスを表すクラスです。ここでは、探索したサービスの中から目的のImmediate AlertサービスとBattery Serviceサービスを探しています。サービスが見つかった場合、Immediate Alertサービスに対してはAlert Levelキャラクタリスティックの、Battery Serviceサービスに対してはBattery Levelキャラクタリスティックの探索を行っています。
キャラクタリスティックの探索はCBPeripheralのdiscoverCharacteristics:forService:メソッドで行います。1番目のパラメータは探索したいキャラクタリスティックをUUIDの配列で指定し、2番目のパラメータは探索対象のサービスをCBServiceのインスタンスで指定します。
なお利用するサービスによっては、入れ子のサービスを持っている場合があります。今回は行いませんが、入れ子のサービスを探索する場合はCBPeripheralのdiscoverIncludedServices:forService:を呼び出します。
続いて次ページでは、サンプルアプリを完成させ実行します。
1-2-3-4 |
INDEX | ||
iPhone/iPadスマートアプリ開発レシピ(4) iPhoneアプリでBluetooth通信を使うための基礎知識 |
||
Page1 意外と知らない? 「Bluetooth」は3種類ある Bluetooth LE対応機器 iOSデバイスのBluetooth対応状況 「Game Kit」によるBluetooth通信 Game Kitを使ったアプリの実装 |
||
Page2 「Core Bluetooth」によるBluetooth LE通信 |
||
Page3 Core Bluetoothを使ったアプリの実装 |
||
Page4 Bluetoothでスマホは生活に欠かせないものに |
Smart&Social フォーラム トップページへ |
- 夏休みの自由研究にマイコンボードで「電子サイコロ」を作ったり、音楽プログラミングをしたりしてみよう (2017/7/24)
子ども向け電子工作&プログラミング用マイコンボード「chibi:bit」の基本的な使い方を紹介する企画。夏休みの自由研究に「電子サイコロ」を作ったり、音楽プログラミングをしたりしてみよう - 子ども向け電子工作&プログラミング用マイコンボード「chibi:bit」の基本的な使い方 (2017/7/20)
子ども向け電子工作&プログラミング用マイコンボード「chibi:bit」の基本的な使い方を紹介する。夏休みの子どもの自由研究などに役立てつつ、プログラミングを始めるきっかけにしてみてはいかがだろうか - 3DゲームのAIをiOSのSceneKitとGameplayKitで作る基本 (2017/7/10)
3Dゲーム用のフレームワークSceneKitを使った簡単なアプリ制作を通して、3Dゲーム用の人工知能(AI)について学ぶ - UnityアプリをWebGL、UWP、Android、iOS用としてビルドしてみた (2017/6/27)
アプリをWebで実行できるように書き出す方法やWindows上でUWP、Android、iOS用などにビルドする方法について解説する【Windows 10、Unity 5.6に対応】
|
|