[iOS]すれちがい通信(その5) | Cocoa練習帳

[iOS]すれちがい通信(その5)

今回は、Peripheral側だ。

Peripheralが対応しているサービスUUIDを登録する。

...
	
                                                                     queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
	
...

Centralの場合と同様に、Peripheralが利用可能になったら、対応するサービスUUIDを登録する。

- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral
{
    if (peripheral.state != CBPeripheralManagerStatePoweredOn) {
        return;
    }
    self.transferCharacteristic = [[CBMutableCharacteristic alloc] initWithType:[CBUUID UUIDWithString:WIBREE_CHARACTERISTIC_UUID]
                                                                     properties:CBCharacteristicPropertyNotify
                                                                          value:nil
                                                                    permissions:CBAttributePermissionsReadable];
    CBMutableService *transferService = [[CBMutableService alloc] initWithType:[CBUUID UUIDWithString:WIBREE_SERVICE_UUID]
                                                                       primary:YES];
    transferService.characteristics = @[self.transferCharacteristic];
    [self.peripheralManager addService:transferService];
}

- startAdvertising:でもサービスUUIDを設定しているが?だが、Centralに見つけてもらうサービスUUIDとCentralと接続後に問い合わせを受けるサービスUUIDが一致していなくてもいいからのようだ。

Centralからキャラクタリスティックの問い合わせが来たら場合の処理。

- (void)peripheralManager:(CBPeripheralManager *)peripheral
                  central:(CBCentral *)central
didSubscribeToCharacteristic:(CBCharacteristic *)characteristic
{
    self.dataToSend = [[Document sharedDocument].uniqueIdentifier dataUsingEncoding:NSUTF8StringEncoding];
    self.sendDataIndex = 0;
    [self sendData];
}
 
- (void)sendData
{
    static BOOL sendingEOM = NO;
    
    if (sendingEOM) {
        BOOL didSend = [self.peripheralManager updateValue:[@"EOM" dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil];
        if (didSend) {
            sendingEOM = NO;
        }
        return;
    }
    if (self.sendDataIndex >= self.dataToSend.length) {
        return;
    }
	
    BOOL didSend = YES;   
    while (didSend) {
        NSInteger amountToSend = self.dataToSend.length - self.sendDataIndex;
        if (amountToSend > NOTIFY_MTU) amountToSend = NOTIFY_MTU;
        NSData *chunk = [NSData dataWithBytes:self.dataToSend.bytes+self.sendDataIndex length:amountToSend];
        didSend = [self.peripheralManager updateValue:chunk forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil];
        if (!didSend) {
            return;
        }
        
        NSString *stringFromData = [[NSString alloc] initWithData:chunk encoding:NSUTF8StringEncoding];
        self.sendDataIndex += amountToSend;
        if (self.sendDataIndex >= self.dataToSend.length) {
            sendingEOM = YES;            
            BOOL eomSent = [self.peripheralManager updateValue:[@"EOM" dataUsingEncoding:NSUTF8StringEncoding] forCharacteristic:self.transferCharacteristic onSubscribedCentrals:nil];
            if (eomSent) {
                sendingEOM = NO;
            }
            return;
        }
    }
}
 
- (void)peripheralManagerIsReadyToUpdateSubscribers:(CBPeripheralManager *)peripheral
{
    [self sendData];
}

BLEでは、一回の通信で遅れるデータサイズは小さいので細切れにして送っている。

ソースコード GitHubからどうぞ。
https://github.com/murakami/workbook/tree/master/ios/Wibree - GitHub
関連情報 Core Bluetooth Programming Guide
BTLE Central Peripheral Transfer
iPhoneアプリ開発エキスパートガイド iOS 6対応
【Cocoa練習帳】 http://www.bitz.co.jp/weblog/
http://ameblo.jp/bitz/(ミラー・サイト)
iPhoneアプリ開発エキスパートガイド iOS 6対応/インプレスジャパン
¥3,990
Amazon.co.jp