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

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

Core Bluetoothと使ったすれちがい通信だと、アプリケーションがバッググラウンドで動作している場合、通信の頻度が低くなるので、iBeaconを試してみる事にした。


自分で調べた訳ではないので間違っていたら申し訳ないが、iBeaconはBluetooth LEのAdvertisingパケットにiBeacon用の情報を埋め込んだもののようだ。つまり、サービスのスキャンで情報を受け取れるという事か?


まずは、バックグラウンドでもすれちがい通信できるようにInfo.plistを設定する。


Info.plist


iBeacon関連のフレームワークを使うとコードは簡素になる。Periperal側は以下のとおり。


@implementation BeaconPeripheralResponseParser
...
- (void)parse
{
    self.state = kBeaconPeripheralStateAdvertising;
    
    /* CBPeripheralManagerを生成 */
    self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self
                                                                     queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
    if (! self.peripheralManager) {
        /* CBPeripheralManagerの初期化失敗 */
        self.state = kBeaconPeripheralStateError;
        self.error = [self _errorWithCode:kBeaconPeripheralResponseParserGenericError
                     localizedDescription:@"CBPeripheralManagerの初期化に失敗しました。"];
        return;
    }
    
    /* ビーコン領域を生成 */
    NSUUID  *uuid = [[NSUUID alloc] initWithUUIDString:BEACON_SERVICE_UUID];
    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid
                                                                major:12345
                                                                minor:67890
                                                           identifier:@"demo.Wibree.BeaconCentralResponseParser"];
    if (! self.beaconRegion) {
        /* ビーコン領域の初期化失敗 */
        self.state = kBeaconPeripheralStateError;
        self.error = [self _errorWithCode:kBeaconPeripheralResponseParserGenericError
                     localizedDescription:@"ビーコン領域の初期化に失敗しました。"];
        self.peripheralManager = nil;
        return;
    }
    
    /* 告知開始 */
    NSDictionary    *dictionary = [self.beaconRegion peripheralDataWithMeasuredPower:nil];
    [self.peripheralManager startAdvertising:dictionary];
}
...
@end

Central側はこうなる。


@implementation BeaconCentralResponseParser
...
- (void)parse
{
    self.state = kBeaconCentralStateScanning;
    
    /* CLLocationManagerを生成 */
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    if (! self.locationManager) {
        /* CLLocationManagerの初期化失敗 */
        self.state = kBeaconCentralStateError;
        self.error = [self _errorWithCode:kBeaconCentralResponseParserGenericError
                     localizedDescription:@"CLLocationManagerの初期化に失敗しました。"];
        return;
    }
    
    /* ビーコン領域を生成 */
    NSUUID  *uuid = [[NSUUID alloc] initWithUUIDString:BEACON_SERVICE_UUID];
    self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"demo.Wibree.BeaconCentralResponseParser"];
    if (! self.beaconRegion) {
        /* ビーコン領域の初期化失敗 */
        self.state = kBeaconCentralStateError;
        self.error = [self _errorWithCode:kBeaconCentralResponseParserGenericError
                     localizedDescription:@"ビーコン領域の初期化に失敗しました。"];
        self.locationManager = nil;
        return;
    }
    
    /* ビーコン領域の出入りを監視 */
    [self.locationManager startMonitoringForRegion:self.beaconRegion];
    
    /* 距離を監視 */
    [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}
...
@end

ビーコンが見つかるとCLLocationManagerDelegateのデリゲート・メソッドが呼ばれるので、それを実装する事になる。


@implementation BeaconCentralResponseParser
...
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    if ([self.delegate respondsToSelector:@selector(beaconCentralResponseParser:didEnterRegion:)]) {
        [self.delegate beaconCentralResponseParser:self didEnterRegion:region];
    }
}
 
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    if ([self.delegate respondsToSelector:@selector(beaconCentralResponseParser:didExitRegion:)]) {
        [self.delegate beaconCentralResponseParser:self didExitRegion:region];
    }
}
 
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
    if ([self.delegate respondsToSelector:@selector(beaconCentralResponseParser:didRangeBeacons:inRegion:)]) {
        [self.delegate beaconCentralResponseParser:self didRangeBeacons:beacons inRegion:region];
    }
}
...
@end

ソースコード
GitHubからどうぞ。

関連情報

【Cocoa練習帳】
http://ameblo.jp/bitz/(ミラー・サイト)