iPhone/iPadスマートアプリ開発レシピ
iPhone/iPadスマートアプリ開発レシピ(4)

iPhoneアプリでBluetooth通信を使うための基礎知識


クラスメソッド株式会社
開発部 掛川敦史
2012/6/19

キャラクタリスティックの発見

 キャラクタリスティックが発見されると、CBPeripheralDelegateのperipheral:didDiscoverCharacteristicsForService:error:メソッドが呼び出されます。

- (void)peripheral:(CBPeripheral *)peripheral
didDiscoverCharacteristicsForService:(CBService *)service
             error:(NSError *)error
{
    if (error)
    {
        NSLog(@"didDiscoverCharacteristics error: %@", error.localizedDescription);
        return;
    }
   
    if (service.characteristics.count == 0)
    {
        NSLog(@"didDiscoverCharacteristics no characteristics");
        return;
    }
 
    for (CBCharacteristic *characteristic in service.characteristics)
    {
        if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kUUIDCharacteristicsAlertLevel]])
        {
            // Alert Levelキャラクタリスティックオブジェクトへの参照を保管
            alertLevelCharacteristic = characteristic;
            // 外部デバイス鳴動指示準備完了を通知
            [self.delegate peripheralManagerNotifyAlertReady:self];
        }
        else if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kUUIDCharacteristicsBatteryLevel]])
        {
            // Battery Levelキャラクタリスティックオブジェクトへの参照を保管
            batteryLevelCharacteristic = characteristic;
            // 外部デバイスバッテリー情報取得準備完了を通知
            [self.delegate peripheralManagerCheckBatteryReady:self];
        }
    }
}
- PR -

 CBCharacteristicはキャラクタリスティックを表すクラスです。ここでは、探索されたキャラクタリスティックから目的のAlert LevelキャラクタリスティックとBattery Levelキャラクタリスティックを探しています。接続したデバイスと通信を行う際は、基本的にCBCharacteristic、もしくはディスクリプタを表すCBDescriptorを利用しますので、CBCharacteristicのインスタンスの参照をクラスの変数に格納しておきます。

 なお利用するキャラクタリスティックによっては、ディスクリプタを持っている場合があります。今回は行いませんが、ディスクリプタを利用したい場合はCBPeripheralのdiscoverDescriptorsForCharacteristic:を呼び出して探索を行います。

接続先デバイスからの情報の取得

 通信の準備ができたので、Battery Serviceサービスを利用して接続先のバッテリー残量の情報を取得してみましょう。バッテリー残量の値はBattery Levelキャラクタリスティックに格納されているので、このキャラクタリスティックの最新の値を取得します。

[targetPeripheral readValueForCharacteristic:batteryLevelCharacteristic];

 キャラクタリスティックの値の取得をする場合は、上記コードのようにCBPeripheralのreadValueForCharacteristic:メソッドを利用します。値の取得が完了すると、CBCharacteristicのvalueプロパティが更新され、CBPeripheralDelegateのperipheral:didUpdateValueForCharacteristic:error:メソッドが呼び出されます。

- (void)peripheral:(CBPeripheral *)peripheral
didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic
             error:(NSError *)error
{
    if (error)
    {
        NSLog(@"didUpdateValueForCharacteristic error: %@", error.localizedDescription);
        return;
    }
   
    if ([characteristic isEqual:batteryLevelCharacteristic])
    {
        // バッテリー情報の値を取得
        ushort value;
        NSMutableData *data = [NSMutableData dataWithData:characteristic.value];
        [data increaseLengthBy:8];
        [data getBytes:&value length:sizeof(value)];
        // バッテリー情報取得完了を通知
        [self.delegate peripheralManager:self didCheckBattery:value];
    }
}

 最新の値は、characteristicのvalueプロパティからNSData型のデータとして取り出せます。Battery Levelキャラクタリスティックの仕様で、値は8bitの符号なし整数値となっているため、データのバイト配列の長さを調整してushortの値として取り出します。

 今回のサンプルでは、この値をアラートで表示しています。


接続先デバイスへの情報の通知

 次に、Immediate Alertサービスを利用して接続先のデバイスを鳴動させてみましょう。この動作を確認するためには、接続先のデバイスがImmediate Alertサービスによる鳴動に対応している必要があります。Alert Levelキャラクタリスティックの値を更新して、デバイスを鳴動させます。

ushort value = 2;
NSMutableData *data = [NSMutableData dataWithBytes:&value length:8];
[targetPeripheral writeValue:data
          forCharacteristic:alertLevelCharacteristic
                       type:CBCharacteristicWriteWithoutResponse];

 キャラクタリスティックの値の更新は、上記コードのようにCBPeripheralのwriteValue:forCharacteristic:type:メソッドを利用します。1番目のパラメータには更新する値をNSData型に変換したものを、2番目のパラメータには更新対象のCBCharacteristicのインスタンスを渡します。ここでは、更新する値として「High Alert」を示す整数値の2を指定しています。この値も8bitの符号なし整数値と定められていますので、NSData型に変換した際にバイト配列の長さを調整します。

 3番目のパラメータは、接続先デバイスへの更新通知完了時にレスポンスを受け取るかを指定します。ただし、実際に更新時にレスポンスが発行されるかどうかは、各キャラクタリスティックの仕様によってあらかじめ決まっています。Alert Levelキャラクタリスティックの更新時にはレスポンスは発行されませんので、ここではCBCharacteristicWriteWithoutResponseを指定しています。

 この処理を実行すると接続先のデバイスが鳴動します。下の写真は実際にデバイスを鳴動させた際の様子です。

 写真では分かりづらいですが、デバイスが鳴動して右下にあるLEDが点灯しています。

 なお情報のやりとりの方法は、各キャラクタリスティックの仕様としてあらかじめ決められています。この情報はキャラクタリスティックの「Propeties」として設定されており、読み取りを表す「Read」や書き込みを表す「Write」など8種類の形式における対応可否が設定されています。

 今回利用したBattery Levelキャラクタリスティックは、「Read」が「Mandatory」となっているため値の取得が実行可能です。

 また、Alert Levelキャラクタリスティックは、「WriteWithoutResponse」が「Mandatory」になっているためレスポンスなしの値の更新が実行可能となっていますが、「Read」が「Excluded」となっているため、値は取得できません。

 デバイスごとの実際の対応状況は、接続時にCBCharacteristicのpropertiesプロパティを参照することによって調べることができます。

Bluetoothでスマホは生活に欠かせないものに

 iOSでは、Game KitやCore Bluetoothを利用することによって、非常に手軽にBluetoothによる通信を利用できます。

 特に、家電や医療・ヘルスケア機器など、Bluetooth LE対応デバイスが今後続々と登場することが予想されている中、スマートフォンはそれらにアクセスする端末としては打って付けのデバイスなので、Core Bluetoothを利用するシーンは、ますます多くなることでしょう。Bluetoothによって、スマートフォンはますます私たちの生活に欠かせないものになりそうですね。

■ @IT関連記事


iPhoneアプリ開発入門
盛り上がるiOS(iPhone・iPad・iPod touch)アプリ開発。そのハウツーや魅力に関する@IT記事一覧です

Objective-C初心者のためのiOS SDKコード例一覧
iPhone/iPadアプリ開発者が知らないと損するまとめ
 iOS SDKを使った@ITのアプリ開発記事のAPIコード例へのリンク集。メソッドやクラスなどの使い方のご参考に
New! Smart & Social」フォーラム 2012/6/13
アプリにGPS・カメラ・タッチなどを使うための記事45選
スマホアプリの作り方【超まとめ】(デバイス編)
 「スマート」のゆえんである、さまざまなセンサやデバイスをアプリに組み込むのに役立つ@IT記事のまとめです
Smart & Social」フォーラム 2012/3/15
iPhoneより多彩なAndroidのセンサをアプリで操作
Androidで動く携帯Javaアプリ作成入門(13) 
Androidで使えるさまざまなセンサを紹介し、加速度や磁気、方位、温度などの値を取得して使うアプリの作り方を解説します
Smart & Social」フォーラム 2010/1/15
開発者が知らないと損するAndroid 4.0の新機能44選
Androidで動く携帯Javaアプリ作成入門(26)
 AndroidビームやWi-Fiダイレクト、ライブエフェクト、顔認識、スクリーンリーダ、ソーシャル系などの新機能をテーマ別に紹介
Smart & Social」フォーラム 2011/11/2
UnityでAndroidのBluetooth制御&Twitter4J連携
Unityで楽々スマホ用3Dアプリ開発入門(3)
 Unityが提供しているネイティブコードとの連携手法の応用編として、デバイスやJavaライブラリとの連携について解説します
Smart & Social」フォーラム 2011/7/29

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 フォーラム トップページへ



Smart & Social フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Smart & Social 記事ランキング

本日 月間