天天品尝iOS7甜点 :: Day 17 :: iBeacons

这篇文章是天天品尝iOS7甜点系列的一部分,你可以查看完整的系列目录:天天品尝iOS7甜点


Introduction - 介绍

在iOS7发布主题中并没有很详细的提及到iBeacons概念。在Bluetooth LE中有些新的特性可以允许近距离的通知和测距。简单的使用通知的是当你接近一个商店的时候然后收到一组特价商品的列表,或者接近你付款账单的时候可以收到发票信息。另外还有很多其他的地方可以使用,我相信在未来的时间里面将会出现一些更加深入创造性的功能。

今天,我们将会查看如何让一个iOS设备扮演成一个iBeacon,并且怎样使用一个不同的设备来估算出到iBeacon设备的距离。我们将会创建一个基于”Hot/Cold”捉迷藏的游戏,iBeacon设备可以隐藏,然后寻找器显示更新估算它们之间的距离。

本章的实例程序能够在github上面进行访问,访问地址:github.com/ShinobiControls/iOS7-day-by-day

Create a beacon

为了能够创建一个应用程序扮演成iBeacon设备,我们需要使用CoreLocation来创建beacon属性,然后需要使用CoreBluetooth在适当的时候来广播。

iBeacons具有一些属性,他们都是唯一的标识。

  • proximityUUID.有一个NSUUID对象它可以标识你的电脑的beacons.你可以拥有相同uuid的beacons.并且设置CoreLocation来通知你是否当前有设备进入到监测范围内。
  • major.是一个NSNumber代表这个beacon物理设备的主要ID,它可以唯一标识一个特性的设备。这个数字代表了一个16位的无符号整数。
  • minor.另外一个NSNumber,它可以代表私人的beacon。

可以通过设置CoreLocation来通知iBeacon中3个可能的ID。也就是说不管什么时候任何在检测范围内的iBeacon具有相同的UUID或者相同的UUID和marjor ID,或者需要一个指定的beacon(UUID、marjor和minor的ID全部匹配)。

我们需要包含CoreLocationCoreBluetooth

1
2
@import CoreLocation;
@import CoreBluetooth;

为了能够让应用程序作为beacon出现,我们需要创建一个CLBeaconRegion对象,指定我们需要的ID。在我们的情况下面,我们之需要设置UUID:

1
_rangedRegion = [[CLBeaconRegion alloc] initWithProximityUUID:_beaconUUID identifier:@"com.shinobicontrols.HotOrCold"];

上述提到的UUID我们是这样创建的:

1
_beaconUUID = [[NSUUID alloc] initWithUUIDString:@"3B2DCB64-A300-4F62-8A11-F6E7A06E4BC0"];

我们可以通过使用使用OS X的uuidgen工具生成一个UUIDString:

1
2
17-ibeacons git:(days/17-ibeacons) ✗ uuidgen
874D949F-3325-4B3F-A6F4-AB5BBCE440F6

我们还需要创建一个CoreBluetooth的外部管理者:

1
_cbPeripheralManager = [[CBPeripheralManger alloc] initWithDelegate:self queue:dispatch_get_main_queue()];

一个CBPeripheralManager需要设置一个代理,然后这个代理需要使用一个方法:

1
2
3
4
#pragma mark - CBPeripheralManager delegate methods
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
// We don't really care...
}

现在我们作为一个iBeacon开始发送通知,然后我们从CLBeaconRegion得到一个字典的设置,然后把他们专递到CBPeripheralManager中开始发送通知:

1
2
3
4
5
6
7
8
9
10
11
- (IBAction)handleHidingButtonPressed:(id)sender {
if (_cbPeripheralManager.state < CBPeripheralManagerStatePoweredOn) {
NSLog(@"Bluetooth must be enabled in order to act as an iBeacon");
return;
}

// Now we construct a CLBeaconRegion to represent ourself
NSDictionary *toBoadcast = [_rangedRegion peripheralDataWithMeasuredPower:@-60];

[_cbPeripheralManager startAdvertising:toBroadcast];
}

首先,在构造通知设置之前,我们需要检查peripheral manager是不是已经启动了,然后开始做广告的细节。measuredPower属性指定了位置为1m内观察监测距离。

我们可以在CBPeripheralManger对象中调用stopAdvertising方法来停止iBeacon。

Beacon Ranging - Beancon测距

使用CoreLocation,当一个具有详细ID的iBeacon出现在我们的监测范围内的时候,我们就可以收到通知。在我们的”Hot/Cold”游戏中,我们将在请求范围内更新我们上面创建的beacon。

我们需要创建一个CoreLocation CLLocationManager:

1
2
_clLocationManager = [CLLocationManager new];
_clLocationManager.delegate = self;

我们已经设置好了代理,接下来就是实现代理中的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
if ([region isEqual:_rangedRegion]) {
// Let's just take the first beacon
CLBeacon *beacon = [beacons firstObject];
self.statusLabel.textColor = [UIColor whiteColor];
self.signalStrengthLabel.textColor = [UIColor whiteColor];
self.signalStrengthLabel.text = [NSString stringWithFormat:@"%ddB", beacon.rssi];
switch (beacon.proximity) {
case CLProximityUnknown: {
self.view.backgroundColor = [UIColor blueColor];
[self setStatus:@"Freezing!"];
}
break;

case CLProximityFar: {
self.view.backgroundColor = [UIColor blueColor];
[self setStatus:@"Cold!"];
}
break;

case CLProximityImmediate: {
self.view.backgroundColor = [UIColor purpleColor];
[self setStatus:@"Warmer"];
}
break;

case CLProximityNear: {
self.view.backgroundColor = [UIColor redColor];
[self setStatus:@"Hot!"];
}
break;

default:
break;
}
}
}

这个代理方法响应设备与beacons的距离更新。这个代理方法被调用的频率是1Hz,并且给方法提供了一个装有beacons的数组,一个CLBeacon有属性确定它的唯一标识。我们将会通过这个来设置视图的背景色,更新标签的状态可以通过下面的工具方法进行设置:

1
2
3
4
- (void)setStatus:(NSString *)status {
self.statusLabel.hidden = NO;
self.statusLabel.text = status;
}

为了是代理的方法能够被调用,我们需要让location manager开启寻找beacon:

1
[_clLocationManager startRangeingBeaconsInRegion:_rangeRegion];

还有一个方法可以用来停止对beacons的监测:

1
[_clLocationManager stopRangingBeaconsInRegion:_rangeRegion];

如果你在两个设置上面运行这个应用程序(其中一个设置具有Bluetooth LE),设置一个隐藏和一个进行查找:

Conclusion - 总结

iBeacons提供出色的潜力——他们甚至可以iOS7的最具破坏性的新特性之一。我认为他们都是苹果的答案,最后一击,NFC的移动设备。希望手机不仅会很快我们得到正确的信息当我们到达一个服务台,但我们也开始看到室内导航。我鼓励你去看看iBeacon API——它不是很复杂,我期待您的创新使用!

本文翻译自:iOS7 Day-by-Day :: Day 17 :: iBeacons

文章目录
  1. 1. Introduction - 介绍
  2. 2. Create a beacon
  3. 3. Beacon Ranging - Beancon测距
  4. 4. Conclusion - 总结
,