2014年1月25日土曜日

iBeaconを受信する

uuidgenコマンドを使って、proximity IDとして使用するUUIDを事前準備しておく。

$ uuidgen


iBeacon受信処理を行うクラスにおいて、CoreLocationをインポートした上でCLLocationManagerDelegateプロトコルを実装(適合)する。各メソッドの意味等については下記コード内のコメントを要参照。
@implementation BLGViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    if ([CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]]) {
        self.locationManager = [[CLLocationManager alloc] init];
        self.locationManager.delegate = self;

        // identifierについては、アプリ内でどのリージョンであるかを判別するために使用
        NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:BLGViewControllerProximityUUID];
        self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:kIdentifier];
        
        // いずれもデフォルト設定値
        self.beaconRegion.notifyOnEntry = YES;
        self.beaconRegion.notifyOnExit = YES;
        self.beaconRegion.notifyEntryStateOnDisplay = NO;
        
        // 領域観測を開始する
        [self.locationManager startMonitoringForRegion:self.beaconRegion];
    }
}

#pragma mark - CLLocationManagerDelegate

// 領域観測が正常に開始されると呼ばれる
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
{
    // 非同期に実行し、CLLocationManagerDelegateに結果を配送する
    // (locationManager:didDetermineState:forRegion:メソッド要実装)
    [self.locationManager requestStateForRegion:self.beaconRegion];
}

// 領域に関する状態を取得する
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
    switch (state) {
        case CLRegionStateInside:
            NSLog(@"state is CLRegionStateInside");
            self.stateLabel.text = @"CLRegionStateInside";
            // 領域内にいるので、測距を開始する
            if ([region isMemberOfClass:[CLBeaconRegion class]] && [CLLocationManager isRangingAvailable]) {
                [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
            }
            break;
        case CLRegionStateOutside:
            NSLog(@"state is CLRegionStateOutside");
            self.stateLabel.text = @"CLRegionStateOutside";
            break;
        case CLRegionStateUnknown:
            NSLog(@"state is CLRegionStateUnknown");
            self.stateLabel.text = @"CLRegionStateUnknown";
            break;
        default:
            NSLog(@"state is UNKNOWN");
            self.stateLabel.text = @"UNKNOWN";
            break;
    }
}

// 領域に入ると呼ばれる
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    // 領域に入ったので、測距を開始する
    if ([region isMemberOfClass:[CLBeaconRegion class]] && [CLLocationManager isRangingAvailable]) {
        [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
    }
}

// 領域から出ると呼ばれる
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    if ([region isMemberOfClass:[CLBeaconRegion class]] && [CLLocationManager isRangingAvailable]) {
        [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
    }
}

// 領域内でビーコンを受信する度に呼ばれる(実機で確認する限りでは約1秒毎)
// ビーコンの状態が変わった時も呼ばれる
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
    if ([beacons count] > 0) {
        // 最も近くにあるビーコンが配列の先頭にあるように、デバイスからの距離によって整列されている
        CLBeacon *nearestBeacon = beacons.firstObject;
        NSString *proximityStr;
        
        switch (nearestBeacon.proximity) {
            case CLProximityImmediate:
                proximityStr = @"CLProximityImmediate";
                break;
            case CLProximityNear:
                proximityStr = @"CLProximityNear";
                break;
            case CLProximityFar:
                proximityStr = @"CLProximityFar";
                break;
            case CLProximityUnknown:
                proximityStr = @"CLProximityUnknown";
                break;
            default:
                proximityStr = @"UNKNOWN";
                break;
        }

        // ビーコン識別情報
        self.uuidLabel.text = nearestBeacon.proximityUUID.UUIDString;
        self.majorLabel.text = [NSString stringWithFormat:@"%@", nearestBeacon.major];
        self.minorLabel.text = [NSString stringWithFormat:@"%@", nearestBeacon.minor];
        
        // アドバタイズしているビーコンまでの距離に関する情報
        self.proximityLabel.text = proximityStr;
        self.rssiLabel.text = [NSString stringWithFormat:@"%ld [dB]", (long)nearestBeacon.rssi];
        self.accuracyLabel.text = [NSString stringWithFormat:@"%.0f [m]", nearestBeacon.accuracy];
    }
}

// アプリのロケーションサービスに関するアクセス許可状態に変更があると呼ばれる
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    NSLog(@"%s", __func__);
    switch (status) {
        case kCLAuthorizationStatusAuthorized:
            NSLog(@"kCLAuthorizationStatusAuthorized");
            break;
        case kCLAuthorizationStatusRestricted:
            NSLog(@"kCLAuthorizationStatusRestricted");
            break;
        case kCLAuthorizationStatusDenied:
            NSLog(@"kCLAuthorizationStatusDenied");
            break;
        case kCLAuthorizationStatusNotDetermined:
            NSLog(@"CLAuthorizationStatusNotDetermined");
            break;
        default:
            NSLog(@"UNKNOWN");
            break;
    }
}

@end

[参考URL]
[iOS 7] 新たな領域観測サービス iBeacon を使ってみる
iBeaconの解説

0 件のコメント:

コメントを投稿