Ios corebluetooth beginner

33
iOS CoreBluetooth 入門 @79SHINSUKE 西川慎介 ヱビス株式会社 webisu-inc.co.jp 2014-03-20

Transcript of Ios corebluetooth beginner

Page 1: Ios corebluetooth beginner

iOS CoreBluetooth 入門

!@79SHINSUKE 西川慎介

ヱビス株式会社 webisu-inc.co.jp 2014-03-20

Page 2: Ios corebluetooth beginner

・BLEの通信規格   デバイスの種類ごとにある !

・手順書   いつ、どんなデータ !

・たくさんある

プロファイル

Page 3: Ios corebluetooth beginner

・Core Bluetoothが対応しているプロファイル !

・サービス(BLEデバイスの機能) !

・キャラクテリスティック(特性) !

・GATTベースのプロファイルもたくさんある !

GATT(Generic Attribute Profile)

Page 4: Ios corebluetooth beginner

・BLEデバイスを見つける ・BLEデバイスに接続する ・BLEデバイスに対するRead/Write ・通信するデータはバイトデータなので何でもOK.動的データも。 ・ペアリングすると暗号化される ・バックグラウンドでも動く

Core Bluetoothフレームワーク

Page 5: Ios corebluetooth beginner

バックグラウンド  ・Info.listで宣言

UIBackgroundModes:bluetooth-central UIBackgroundModes:bluetooth-peripheral !

 ・デバイスの検知 (セントラル)  ・アドバタイズ発信 (ペリフェラル)     UUIDが送信されないので、セントラルがUUIDで検索している場合は見つけられない

!!!

Page 6: Ios corebluetooth beginner

・1つ以上のサービスを提供する !

・アドバタイズ !

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

・たとえば、iBeaconで利用されるBeacon

ペリフェラル(Peripheral)

Page 7: Ios corebluetooth beginner

ペリフェラルのデータ構造 !

!

CBMutableService

CBPeripheralManager

CBMutableService

CBMutableCharacteristic

CBMutableCharacteristic

CBMutableCharacteristic

CBMutableCharacteristic

CBPeripheralManager *_peripheralManager; CBMutableService *_service; CBMutableCharacteristic *_characteristic;

Page 8: Ios corebluetooth beginner

・アドバタイズしているペリフェラルを見つける !

・アドバタイズしているペリフェラルに接続する !!

・データ通信(Read/Write)

セントラル(Central)

Page 9: Ios corebluetooth beginner

iOSデバイス間で セントラル-ペリフェラルに通信してみました

Page 10: Ios corebluetooth beginner

ペリフェラルのコード

Page 11: Ios corebluetooth beginner

#import <CoreBluetooth/CoreBluetooth.h> !@interface ViewController : UIViewController<CBPeripheralManagerDelegate> @end !@implementation ViewController { CBPeripheralManager *_peripheralManager; CBMutableService *_service; CBMutableCharacteristic *_characteristic; NSData *_value; } !!!- (void)viewDidLoad { [super viewDidLoad]; ! // データ _value = [@"Hello World" dataUsingEncoding:NSUTF8StringEncoding]; // ペリフェラルマネージャをつくる _peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil]; } !!!- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral { if (peripheral.state == CBPeripheralManagerStatePoweredOn) { [self startService]; } }

Page 12: Ios corebluetooth beginner

#import <CoreBluetooth/CoreBluetooth.h> !@interface ViewController : UIViewController<CBPeripheralManagerDelegate> @end !@implementation ViewController { CBPeripheralManager *_peripheralManager; CBMutableService *_service; CBMutableCharacteristic *_characteristic; NSData *_value; } !!!- (void)viewDidLoad { [super viewDidLoad]; ! // データ _value = [@"Hello World" dataUsingEncoding:NSUTF8StringEncoding]; // ペリフェラルマネージャをつくる _peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil]; } !!!- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral { if (peripheral.state == CBPeripheralManagerStatePoweredOn) { [self startService]; } }

Page 13: Ios corebluetooth beginner

#import <CoreBluetooth/CoreBluetooth.h> !@interface ViewController : UIViewController<CBPeripheralManagerDelegate> @end !@implementation ViewController { CBPeripheralManager *_peripheralManager; CBMutableService *_service; CBMutableCharacteristic *_characteristic; NSData *_value; } !!!- (void)viewDidLoad { [super viewDidLoad]; ! // データ _value = [@"Hello World" dataUsingEncoding:NSUTF8StringEncoding]; // ペリフェラルマネージャをつくる _peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil]; } !!!- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral { if (peripheral.state == CBPeripheralManagerStatePoweredOn) { [self startService]; } }

Page 14: Ios corebluetooth beginner

#import <CoreBluetooth/CoreBluetooth.h> !@interface ViewController : UIViewController<CBPeripheralManagerDelegate> @end !@implementation ViewController { CBPeripheralManager *_peripheralManager; CBMutableService *_service; CBMutableCharacteristic *_characteristic; NSData *_value; } !!!- (void)viewDidLoad { [super viewDidLoad]; ! // データ _value = [@"Hello World" dataUsingEncoding:NSUTF8StringEncoding]; // ペリフェラルマネージャをつくる _peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil]; } !!!- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral { if (peripheral.state == CBPeripheralManagerStatePoweredOn) { [self startService]; } }

Page 15: Ios corebluetooth beginner

- (void)startService { NSLog(@"start service"); // サービスをつくる _service = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:@"74E493FC-B56E-471E-91E5-C63DC9CD4716"] primary:YES]; ! //キャラクテリスティックをつくる _characteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:@"97D158FF-A5F4-4D13-A97F-86D460CF1FD2"] properties:(CBCharacteristicPropertyRead|CBCharacteristicPropertyWrite|CBCharacteristicPropertyNotify) value:nil //動的な値をわたすときはnil permissions:(CBAttributePermissionsReadable|CBAttributePermissionsWriteable)]; ! // サービスにキャラクテリスティックをセット _service.characteristics = @[_characteristic]; // マネージャにサービスを登録 [_peripheralManager addService:_service]; // サービスをアドバタイズする [_peripheralManager startAdvertising:@{ CBAdvertisementDataLocalNameKey: @"iBLE", CBAdvertisementDataServiceUUIDsKey:@[_service.UUID] }]; }

Page 16: Ios corebluetooth beginner

- (void)startService { NSLog(@"start service"); // サービスをつくる _service = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:@"74E493FC-B56E-471E-91E5-C63DC9CD4716"] primary:YES]; ! //キャラクテリスティックをつくる _characteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:@"97D158FF-A5F4-4D13-A97F-86D460CF1FD2"] properties:(CBCharacteristicPropertyRead|CBCharacteristicPropertyWrite|CBCharacteristicPropertyNotify) value:nil //動的な値をわたすときはnil permissions:(CBAttributePermissionsReadable|CBAttributePermissionsWriteable)]; ! // サービスにキャラクテリスティックをセット _service.characteristics = @[_characteristic]; // マネージャにサービスを登録 [_peripheralManager addService:_service]; // サービスをアドバタイズする [_peripheralManager startAdvertising:@{ CBAdvertisementDataLocalNameKey: @"iBLE", CBAdvertisementDataServiceUUIDsKey:@[_service.UUID] }]; }

Page 17: Ios corebluetooth beginner

- (void)startService { NSLog(@"start service"); // サービスをつくる _service = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:@"74E493FC-B56E-471E-91E5-C63DC9CD4716"] primary:YES]; ! //キャラクテリスティックをつくる _characteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:@"97D158FF-A5F4-4D13-A97F-86D460CF1FD2"] properties:(CBCharacteristicPropertyRead|CBCharacteristicPropertyWrite|CBCharacteristicPropertyNotify) value:nil //動的な値をわたすときはnil permissions:(CBAttributePermissionsReadable|CBAttributePermissionsWriteable)]; ! // サービスにキャラクテリスティックをセット _service.characteristics = @[_characteristic]; // マネージャにサービスを登録 [_peripheralManager addService:_service]; // サービスをアドバタイズする [_peripheralManager startAdvertising:@{ CBAdvertisementDataLocalNameKey: @"iBLE", CBAdvertisementDataServiceUUIDsKey:@[_service.UUID] }]; }

Page 18: Ios corebluetooth beginner

- (void)startService { NSLog(@"start service"); // サービスをつくる _service = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:@"74E493FC-B56E-471E-91E5-C63DC9CD4716"] primary:YES]; ! //キャラクテリスティックをつくる _characteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:@"97D158FF-A5F4-4D13-A97F-86D460CF1FD2"] properties:(CBCharacteristicPropertyRead|CBCharacteristicPropertyWrite|CBCharacteristicPropertyNotify) value:nil //動的な値をわたすときはnil permissions:(CBAttributePermissionsReadable|CBAttributePermissionsWriteable)]; ! // サービスにキャラクテリスティックをセット _service.characteristics = @[_characteristic]; // マネージャにサービスを登録 [_peripheralManager addService:_service]; // サービスをアドバタイズする [_peripheralManager startAdvertising:@{ CBAdvertisementDataLocalNameKey: @"iBLE", CBAdvertisementDataServiceUUIDsKey:@[_service.UUID] }]; }

Page 19: Ios corebluetooth beginner

// サービスを追加 - (void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error !{ if (error) { // エラー処理 } } !!!!// Centralからの接続待ち状態 - (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error { if (error) { // エラー処理 } }

Page 20: Ios corebluetooth beginner

// セントラルからの読み取り要求 -(void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request { NSLog(@"didReceiveReadRequest: %@",request); request.value = _value; [_peripheralManager respondToRequest:request withResult:CBATTErrorSuccess]; }

Page 21: Ios corebluetooth beginner

セントラルのコード

Page 22: Ios corebluetooth beginner

#import <CoreBluetooth/CoreBluetooth.h> !@interface ViewController : UIViewController<CBCentralManagerDelegate,CBPeripheralManagerDelegate> @end !@implementation ViewController { CBCentralManager *_centralManager; CBPeripheral *_peripheral; } !!!- (void)viewDidLoad { [super viewDidLoad]; ! //セントラルマネージャを起動 _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; } !!!

- (void)centralManagerDidUpdateState:(CBCentralManager *)central { ! if (central.state == CBCentralManagerStatePoweredOn) { //アドバタイズしているペリフェラルを検出する(探索対象のデバイスが持つサービスを指定) NSArray *services = [NSArray arrayWithObjects:[CBUUID UUIDWithString:kServiceUUID], nil]; // 単一デバイスの発見イベントを重複して発行させない NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey]; // デバイスの探索を開始 [_centralManager scanForPeripheralsWithServices:services options:options]; } }

Page 23: Ios corebluetooth beginner

#import <CoreBluetooth/CoreBluetooth.h> !@interface ViewController : UIViewController<CBCentralManagerDelegate,CBPeripheralManagerDelegate> @end !@implementation ViewController { CBCentralManager *_centralManager; CBPeripheral *_peripheral; } !!!- (void)viewDidLoad { [super viewDidLoad]; ! //セントラルマネージャを起動 _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; } !!!

- (void)centralManagerDidUpdateState:(CBCentralManager *)central { ! if (central.state == CBCentralManagerStatePoweredOn) { //アドバタイズしているペリフェラルを検出する(探索対象のデバイスが持つサービスを指定) NSArray *services = [NSArray arrayWithObjects:[CBUUID UUIDWithString:kServiceUUID], nil]; // 単一デバイスの発見イベントを重複して発行させない NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey]; // デバイスの探索を開始 [_centralManager scanForPeripheralsWithServices:services options:options]; } }

Page 24: Ios corebluetooth beginner

#import <CoreBluetooth/CoreBluetooth.h> !@interface ViewController : UIViewController<CBCentralManagerDelegate,CBPeripheralManagerDelegate> @end !@implementation ViewController { CBCentralManager *_centralManager; CBPeripheral *_peripheral; } !!!- (void)viewDidLoad { [super viewDidLoad]; ! //セントラルマネージャを起動 _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; } !!!

- (void)centralManagerDidUpdateState:(CBCentralManager *)central { ! if (central.state == CBCentralManagerStatePoweredOn) { //アドバタイズしているペリフェラルを検出する(探索対象のデバイスが持つサービスを指定) NSArray *services = [NSArray arrayWithObjects:[CBUUID UUIDWithString:kServiceUUID], nil]; // 単一デバイスの発見イベントを重複して発行させない NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey]; // デバイスの探索を開始 [_centralManager scanForPeripheralsWithServices:services options:options]; } }

Page 25: Ios corebluetooth beginner

#import <CoreBluetooth/CoreBluetooth.h> !@interface ViewController : UIViewController<CBCentralManagerDelegate,CBPeripheralManagerDelegate> @end !@implementation ViewController { CBCentralManager *_centralManager; CBPeripheral *_peripheral; } !!!- (void)viewDidLoad { [super viewDidLoad]; ! //セントラルマネージャを起動 _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; } !!!

- (void)centralManagerDidUpdateState:(CBCentralManager *)central { ! if (central.state == CBCentralManagerStatePoweredOn) { //アドバタイズしているペリフェラルを検出する(探索対象のデバイスが持つサービスを指定) NSArray *services = [NSArray arrayWithObjects:[CBUUID UUIDWithString:kServiceUUID], nil]; // 単一デバイスの発見イベントを重複して発行させない NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey]; // デバイスの探索を開始 [_centralManager scanForPeripheralsWithServices:services options:options]; } }

Page 26: Ios corebluetooth beginner

#import <CoreBluetooth/CoreBluetooth.h> !@interface ViewController : UIViewController<CBCentralManagerDelegate,CBPeripheralManagerDelegate> @end !@implementation ViewController { CBCentralManager *_centralManager; CBPeripheral *_peripheral; } !!!- (void)viewDidLoad { [super viewDidLoad]; ! //セントラルマネージャを起動 _centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil]; } !!!

- (void)centralManagerDidUpdateState:(CBCentralManager *)central { ! if (central.state == CBCentralManagerStatePoweredOn) { //アドバタイズしているペリフェラルを検出する(探索対象のデバイスが持つサービスを指定) NSArray *services = [NSArray arrayWithObjects:[CBUUID UUIDWithString:kServiceUUID], nil]; // 単一デバイスの発見イベントを重複して発行させない NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:CBCentralManagerScanOptionAllowDuplicatesKey]; // デバイスの探索を開始 [_centralManager scanForPeripheralsWithServices:services options:options]; } }

Page 27: Ios corebluetooth beginner

// ペリフェラルが見つかったら通知 - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI { NSLog(@"Discoverd peripheral: %@", peripheral); // ペリフェラルに接続 _peripheral = peripheral; _peripheral.delegate = self; [_centralManager connectPeripheral:_peripheral options:nil]; } !!!!//ペリフェラルへの接続に失敗 - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error { NSLog(@"Fail To Connetct Peripheral"); [self cleanup]; }

Page 28: Ios corebluetooth beginner

//ペリフェラルへの接続完了 - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral { NSLog(@"Connetcted Peripheral"); // 見つかったので他のペリフェラルのスキャンを停止 [_centralManager stopScan]; _peripheral = peripheral; _peripheral.delegate = self; // サービス接続 [_peripheral discoverServices:@[[CBUUID UUIDWithString:kServiceUUID]]]; } !- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error { if (error) { [self cleanup]; return; } for (CBService *service in peripheral.services) { [peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:kCharacteristicUUID]] forService:service]; } }

Page 29: Ios corebluetooth beginner

//ペリフェラルへの接続完了 - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral { NSLog(@"Connetcted Peripheral"); // 見つかったので他のペリフェラルのスキャンを停止 [_centralManager stopScan]; _peripheral = peripheral; _peripheral.delegate = self; // サービス接続 [_peripheral discoverServices:@[[CBUUID UUIDWithString:kServiceUUID]]]; } !- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error { if (error) { [self cleanup]; return; } for (CBService *service in peripheral.services) { [peripheral discoverCharacteristics:@[[CBUUID UUIDWithString:kCharacteristicUUID]] forService:service]; } }

Page 30: Ios corebluetooth beginner

// 指定されたサービスのキャラクタリスティックを検出 - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error { if (error) { [self cleanup]; return; } for (CBCharacteristic *characteristic in service.characteristics) { if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kCharacteristicUUID]]) { // 読み取り要求 [peripheral readValueForCharacteristic:characteristic]; } } } !// 読み取り要求 - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error { if (error) { NSLog(@"Error"); return; } NSString *value= [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding]; NSLog(@"characteristic value is %@", value); }

Page 31: Ios corebluetooth beginner

// 指定されたサービスのキャラクタリスティックを検出 - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error { if (error) { [self cleanup]; return; } for (CBCharacteristic *characteristic in service.characteristics) { if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kCharacteristicUUID]]) { // 読み取り要求 [peripheral readValueForCharacteristic:characteristic]; } } } !// 読み取り要求 - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error { if (error) { NSLog(@"Error"); return; } NSString *value= [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding]; NSLog(@"characteristic value is %@", value); }

Page 32: Ios corebluetooth beginner

・writeValue [_peripheral writeValue:dataToWrite forCharacteristic:_characteristic type:CBCharacteristicWriteWithResponse]; !

![_peripheral writeValue:dataToWrite forCharacteristic:_characteristic type:CBCharacteristicWriteWithoutResponse];

!

・notify [_peripheral setNotifyValue:YES forCharacteristic:_characteristic]; !

Page 33: Ios corebluetooth beginner

ありがとうございました!