iBeacon 介绍
iBeacon 是苹果公司在 iOS7上配备的新功能,可以让附近的手持电子设备检测到一个由一个 iBeacon 信号发射器发出的蓝牙信号.
它采用了基于蓝牙4.0的低功耗蓝牙技术(Bluetooth Low Energy, BLE),主要是用作辅助室内定位的功能.
iBeacon 原理
iBeacon中有两个角色:
发射者
: 一般都是各种硬件
接收者
: 一般都是智能终端(手机)
发射者通过BLE 的广告通信通道,以一定时间间隔向外广播数据包(一般是每秒两三次),接收者可以通过终端提供的功能来接收,达到信息的交互.
每个信号中至少携带了三个主要信息:UUID
, Major
, Minor
,这三个信号组成了一个 iBeacon 的唯一标识符.
当 iOS设备接收到 iBeacon 信号时,还会有其他重要信息:
rssi: 信号强度
proximity: 发射者到接收者的距离(不是数值,是个枚举: Unknow, Immediate, Near, Far)
accuracy: 水平精度
BLE 发射的是2.4GHz 的信号,任何物理阻碍物都会影响 iBeacon 的信号.
其实,发射者也就是硬件向四周不停地广播信号,而信号就像是水波一样像四周扩散,越靠近中心点的水波越高也就是 rssi 信号越强,而一旦有东西阻隔,信号就会减弱甚至消失,而且一旦超过一定值,信号就会消失,这说明 iBeacon 的广播范围是有限的.
说完发射者,再来说接收者.
接收者提供了两种方式来接收iBeacon信号:
-
Monitoring
: 可以用来在设备进入/退出某个地理区域时获得通知, 使用这种方法可以在应用程序的后台运行时检测iBeacon,但是只能同时检测20个region区域,并且不能够推测设备与iBeacon的距离. -
Ranging
: iOS 7之后提供的 API, 用于确定设备的近似距离iBeacon 技术,可以用来检测某区域内的所有iBeacons,并且可以精度估计发射者与接收者的距离,这个使用如下四中接近状态来表示:
相关 API
终于说到 API, 这个是可能踩坑比较多的地方了.
- 需要打开 GPS 定位和蓝牙.
- iBeacon 的 API 是在 CoreLocation, 但iBeacon 必须要打开蓝牙,如果需要判断蓝牙,需要用到 CoreBluetooth 框架.
- Monitoring和 Ranging 是两种监测方式,可以一起用,但是需要区分业务需求,两种一起用会有小坑.
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self; // 遵循代理
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
// 请求用户授权定位权限
[self.locationManager requestAlwaysAuthorization];
}
CLBeaconRegion 的创建
CLBeaconRegion *region = [[CLBeaconRegion alloc]initWithProximityUUID:#UUID# identifier: #identifier#];
region.notifyOnExit = YES;
region.notifyOnEntry = YES;
region.notifyEntryStateOnDisplay = YES;
接下来是两种方式监测 iBeacon 方式:
// Monitoring
// 开始检测区域
[self.locationManager startMonitoringForRegion:beaconRegion];
// 停止检测区域
[self.locationManager stopMonitoringForRegion:beaconRegion];
// delegate
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
// 设备进入该区域时的回调
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
// 设备退出该区域时的回调
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
// 有错误产生时的回调
- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(nullable CLRegion *)region withError:(NSError *)error
// Ranging
// 开始检测区域
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
// 停止检测区域
[self.locationManager stopRangingBeaconsInRegion:beaconRegion];
// delegate
// 检测到区域内的iBeacons的回调函数,包含监测到的所有 iBeacon 的信息
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray<CLBeacon *> *)beacons inRegion:(CLBeaconRegion *)region
// 有错误产生时的回调
- (void)locationManager:(CLLocationManager *)manager rangingBeaconsDidFailForRegion:(CLBeaconRegion *)region withError:(NSError *)error
注意事项(坑点)
- Monitoring和Ranging最好不要一起用,会莫名其妙出现这样的 log:
[Client] {"msg":"Fence: onClientEventRegionState, invalid state", "regionState":"0"}
google也搜不到why,在后来我关掉Monitoring再也没有出现这个 log.
- iBeacon 这个功能的 API 是在 CoreLocation 框架, 但是 iBeacon 必须要打开蓝牙,不然会一直失败, 蓝牙又要用到 CoreBluetooth 来监听状态.(....)
参考
---如果你有兴趣, 请直接去这里:
https://developer.apple.com/ibeacon/Getting-Started-with-iBeacon.pdf
https://medium.com/@jerrywang0420/ibeacon-%E6%95%99%E5%AD%B8-swift-3-ios-1d4ea88311be