Ios corebluetooth beginner
-
Upload
shinsuke79 -
Category
Software
-
view
1.688 -
download
4
Transcript of Ios corebluetooth beginner
・BLEの通信規格 デバイスの種類ごとにある !
・手順書 いつ、どんなデータ !
・たくさんある
プロファイル
・Core Bluetoothが対応しているプロファイル !
・サービス(BLEデバイスの機能) !
・キャラクテリスティック(特性) !
・GATTベースのプロファイルもたくさんある !
GATT(Generic Attribute Profile)
・BLEデバイスを見つける ・BLEデバイスに接続する ・BLEデバイスに対するRead/Write ・通信するデータはバイトデータなので何でもOK.動的データも。 ・ペアリングすると暗号化される ・バックグラウンドでも動く
Core Bluetoothフレームワーク
バックグラウンド ・Info.listで宣言
UIBackgroundModes:bluetooth-central UIBackgroundModes:bluetooth-peripheral !
・デバイスの検知 (セントラル) ・アドバタイズ発信 (ペリフェラル) UUIDが送信されないので、セントラルがUUIDで検索している場合は見つけられない
!!!
・1つ以上のサービスを提供する !
・アドバタイズ !
・アドバタイジング・データ !
・たとえば、iBeaconで利用されるBeacon
ペリフェラル(Peripheral)
ペリフェラルのデータ構造 !
!
CBMutableService
CBPeripheralManager
CBMutableService
CBMutableCharacteristic
CBMutableCharacteristic
CBMutableCharacteristic
CBMutableCharacteristic
CBPeripheralManager *_peripheralManager; CBMutableService *_service; CBMutableCharacteristic *_characteristic;
・アドバタイズしているペリフェラルを見つける !
・アドバタイズしているペリフェラルに接続する !!
・データ通信(Read/Write)
セントラル(Central)
iOSデバイス間で セントラル-ペリフェラルに通信してみました
ペリフェラルのコード
#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]; } }
#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]; } }
#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]; } }
#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]; } }
- (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] }]; }
- (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] }]; }
- (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] }]; }
- (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] }]; }
// サービスを追加 - (void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error !{ if (error) { // エラー処理 } } !!!!// Centralからの接続待ち状態 - (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error { if (error) { // エラー処理 } }
// セントラルからの読み取り要求 -(void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request { NSLog(@"didReceiveReadRequest: %@",request); request.value = _value; [_peripheralManager respondToRequest:request withResult:CBATTErrorSuccess]; }
セントラルのコード
#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]; } }
#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]; } }
#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]; } }
#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]; } }
#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]; } }
// ペリフェラルが見つかったら通知 - (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]; }
//ペリフェラルへの接続完了 - (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]; } }
//ペリフェラルへの接続完了 - (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]; } }
// 指定されたサービスのキャラクタリスティックを検出 - (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); }
// 指定されたサービスのキャラクタリスティックを検出 - (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); }
・writeValue [_peripheral writeValue:dataToWrite forCharacteristic:_characteristic type:CBCharacteristicWriteWithResponse]; !
![_peripheral writeValue:dataToWrite forCharacteristic:_characteristic type:CBCharacteristicWriteWithoutResponse];
!
・notify [_peripheral setNotifyValue:YES forCharacteristic:_characteristic]; !
ありがとうございました!