hackist_green

iBeaconを動かしてみた

みなさん、こんにちは。
リアル連動大好き一階です。
 
アプリを起動すると周囲のBeaconを検知するアプリを作ってみました。
以下実装方法です。

1.CoreLcoationFrameworkを追加する。
2.変数を定義して

@property (nonatomic, strong) CLLocationManager* locationManager;
@property (nonatomic, strong) NSUUID* proximityUUID;
@property (nonatomic, strong) CLBeaconRegion* beaconRegion;
NSString* beaconUUID = @"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX";

※beaconUUIDは事前にEstimote社のサンプルプログラムを動かして取得
 
3.viewDidLoadで測定開始

if ([CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]]) {
	if( _locationManager == nil ) {
		_locationManager = [CLLocationManager new];
		_locationManager.delegate = self;
	}

	_proximityUUID = [[NSUUID alloc] initWithUUIDString:beaconUUID];
	_beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:_proximityUUID identifier:@"EstimoteSampleRegion"];
	[_locationManager startMonitoringForRegion:_beaconRegion];
	// 最初から範囲内にいるとイベントが走らないのでここで走らせておく。
	[_locationManager startRangingBeaconsInRegion:_beaconRegion];
}

※コメントにもありますが”startMonitoringForRegion”を呼び出すとBeaconの監視を開始しますが、この時に対象Beaconが既に近くにあると発見イベントが通知されない仕様になっているので、即Beaconとの距離測定を開始しています。
このBlogによれば上記呼び出し方は誤りとのことなのですが、Blog記載の方法では検知を開始しなかったのでとりあえず修正していません。
※EstimoteのBeacon全てを対象にしているのでinitWithProximityUUIDにmajorやminorを指定していません。
 
4.Beacon発見/ロストイベント

- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region

※Beaconが見つかると”didRangeBeacons”が、Beaconを全て見失うと”didExitRegion”が呼び出されます。
※”didRangeBeacons”の(NSArray *)beaconsには、Frameworkが近いBeaconから順番にセットしてくれているので、自前で距離計算をする必要はありません。
 
5.Beaconの情報に応じた処理

for (CLBeacon* clBeacon in beacons) {
	NSUUID* beaconUUID = clBeacon.proximityUUID;
	NSString *uuid= beaconUUID.UUIDString;
	NSString* proximityString = nil;
	switch (clBeacon.proximity)
	{
		case CLProximityUnknown:
			proximityString = @"Unknown";
			break;
		case CLProximityImmediate:
			proximityString = @"Immediate";
			break;
		case CLProximityNear:
			proximityString = @"Near";
			break;
		case CLProximityFar:
			proximityString = @"Far";
			break;
		default:
			break;
	}

	NSInteger major = [clBeacon.major integerValue];
	if( major == AQUABLUE_BEACON_ID ) {
		NSLog(@"aquaBlue:promixity: %@", proximityString);
	} else if( major == BLUE_BEACON_ID ) {
		NSLog(@"blue:promixity: %@", proximityString);
	}else if( major == LIGHTGREEN_BEACON_ID ) {
		NSLog(@"lightGreen:promixity: %@", proximityString);
	}
}

※EstimoteのBeaconは3色全てmajorの値が異なるので、majorの値を元に3色を識別しています。
※majorの値は事前に端末に3色それぞれを近接させて取得しました。
 
6.ログ出力

for (CLBeacon* clBeacon in beacons) {
	NSUUID* beaconUUID = clBeacon.proximityUUID;
	NSString *uuid= beaconUUID.UUIDString;
	NSString* proximityString = nil;
	switch (clBeacon.proximity)
	{
	    case CLProximityUnknown:
	        proximityString = @"Unknown";
	        break;
	    case CLProximityImmediate:
	        proximityString = @"Immediate";
	        break;
	    case CLProximityNear:
	        proximityString = @"Near";
	        break;
	    case CLProximityFar:
	        proximityString = @"Far";
	        break;
	        
	    default:
	        break;
	}
	NSMutableString* messageString = [NSMutableString string];
	[messageString appendString:proximityString];

	NSString* workString = nil;
	[messageString appendString:@"/"];
	[messageString appendString:@"uuid:"];
	[messageString appendString:uuid];
	[messageString appendString:@"/"];
	[messageString appendString:@"major:"];
	[messageString appendString:[clBeacon.major stringValue]];
	[messageString appendString:@"/"];
	[messageString appendString:@"minor:"];
	[messageString appendString:[clBeacon.minor stringValue]];
	[messageString appendString:@"/"];
	[messageString appendString:@"accuracy:"];
	workString = [NSString stringWithFormat:@"%g", clBeacon.accuracy ];
	[messageString appendString:workString];
	[messageString appendString:@"/"];
	[messageString appendString:@"rssi:"];
	workString = [NSString stringWithFormat:@"%ld", clBeacon.rssi ];
	[messageString appendString:workString];

	NSLog(@"%@", messageString);
}

一応参考までに。
 
意外と簡単に扱うことが出来ます。