iBeacon
是苹果公司2013年9月发布的移动设备用OS(iOS7)上配备的新功能。其工做方式是,配备有低功耗蓝牙(BLE)通讯功能的设备使用BLE
技术向周围发送本身特有的 ID,接收到该 ID 的应用软件会根据该 ID 采起一些行动。html
从我的的角度看: iBeacon
向四面八方不停地广播信号,就像是往平静的水面上扔了一块石子,泛起层层涟漪(俗称水波),波峰至关于 iBeacon 的RSSI
(接受信号强度指示),越靠近中心点的地方波峰越高(RSSI 越大),这个波峰的大小(RSSI 的值)受到扔石子时用力大小(发射功率)和水质(周围环境因子)的影响,离中心点越远水波越趋向于平静,超过了必定值,水波会消失于无形,也就是说 iBeacon 向外广播的距离是有范围的,超过了这个范围,将接受不到 iBeacon 的信号。ios
从iOS开发者的角度看: iBeacon 在 CoreLocation
框架中抽象为CLBeacon
类, 该类有6个属性,分别是:git
proximityUUID
,是一个 NSUUID
,用来标识公司。每一个公司、组织使用的 iBeacon 应该拥有一样的 proximityUUID
。github
major
,主要值,用来识别一组相关联的 beacon,例如在连锁超市的场景中,每一个分店的 beacon 应该拥有一样的 major
。bash
minor
,次要值,则用来区分某个特定的 beacon。app
proximity
,远近范围的,一个枚举值。框架
typedef NS_ENUM(NSInteger, CLProximity) {
CLProximityUnknown,// 无效
CLProximityImmediate,//在几厘米内
CLProximityNear,//在几米内
CLProximityFar//超过 10 米之外,不过在测试中超不过10米就是far
}
复制代码
accuracy
,与iBeacon的距离。ide
rssi
,信号轻度为负值,越接近0信号越强,等于0时没法获取信号强度。函数
Tip:proximityUUID
,major
,minor
这三个属性组成 iBeacon
的惟一标识符。测试
只要进入iBeacon
的范围,就能唤醒 App(大约10秒钟),即便在程序被杀掉的状况下。必要时,可使用UIApplication
类的- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void (^)(void))handler;
方法,请求更多的后台执行时间。
iBeacon的用途:咱们能够用iBeacon
能够进行室内定位(车库,商场),智能打卡,提醒(离开某物体的时候,好比离开家)。
iOS 中 iBeacon 是基于地理位置的微定位技术,虽然借助手机蓝牙进行接收Majro
、Minor
,可是他们在开发工程中没有任何关系。
iBeacon
使用苹果提供CoreLocation
库,然而在 BLE 在开发过程当中使用CoreBluetooth
库。从上面提供的库来看就很清楚了,特别是在 iOS8.0 以后的时候若是想使用iBeacon
,必须让用户点击是否容许XXapp
使用地理位置。若是在第一次使用 iOS App 扫描iBeacon
的时候没有提示这句话,是不可能接收到iBeacon
的信号(除非iOS 8.0之下)。若是是 BLE 则的开发过程当中之须要提示用户打开蓝牙,并不要求其余的地理位置任何信息。
在info.plist
中添加NSLocationAlwaysAndWhenInUseUsageDescription
,NSLocationWhenInUseUsageDescription
,NSLocationAlwaysUsageDescription
,请求地理位置权限。
开启Background Modes
import <CoreLocation/CoreLocation.h>
。
初始化locationManager
和beaconRegion
。
- (CLLocationManager *)locationManager {
if (!_locationManager) {
_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
}
return _locationManager;
}
- (CLBeaconRegion *)beaconRegion {
if (!_beaconRegion) {
_beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:Beacon_Device_UUID] identifier:@"test"];
_beaconRegion.notifyEntryStateOnDisplay = YES;
}
return _beaconRegion;
}
复制代码
CLBeaconRegion
类,提供了3个初始化方法:
//监听该UUID下的全部Beacon设备
- (instancetype)initWithProximityUUID:(NSUUID *)proximityUUID identifier:(NSString *)identifier;
//监听该UUID,major下的全部Beacon设备
- (instancetype)initWithProximityUUID:(NSUUID *)proximityUUID major:(CLBeaconMajorValue)major identifier:(NSString *)identifier;
//监听惟一的Beacon设备
- (instancetype)initWithProximityUUID:(NSUUID *)proximityUUID major:(CLBeaconMajorValue)major minor:(CLBeaconMinorValue)minor identifier:(NSString *)identifier;
复制代码
在开始监控以前,咱们须要使用isMonitoringAvailableForClass
判断设备是否支持,是否容许访问地理位置。
BOOL availableMonitor = [CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]];
if (availableMonitor) {
CLAuthorizationStatus authorizationStatus = [CLLocationManager authorizationStatus];
switch (authorizationStatus) {
case kCLAuthorizationStatusNotDetermined:
[self.locationManager requestAlwaysAuthorization];
break;
case kCLAuthorizationStatusRestricted:
case kCLAuthorizationStatusDenied:
NSLog(@"受限制或者拒绝");
break;
case kCLAuthorizationStatusAuthorizedAlways:
case kCLAuthorizationStatusAuthorizedWhenInUse:{
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
[self.locationManager startMonitoringForRegion:self.beaconRegion];
}
break;
}
} else {
NSLog(@"该设备不支持 CLBeaconRegion 区域检测");
}
复制代码
可用两种方式检测区域Monitoring
或Ranging
方式
Monitoring:能够用来在设备进入/退出某个地理区域时得到通知, 使用这种方法能够在应用程序的后台运行时检测 iBeacon,可是只能同时检测 20 个 region 区域,而且不可以推测设备与 iBeacon 的距离。
// 开始检测区域
[self.locationManager startMonitoringForRegion:beaconRegion];
// 中止检测区域
[self.locationManager stopMonitoringForRegion:beaconRegion];
// Monitoring成功对应回调函数
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region;
// 设备进入该区域时的回调
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region;
// 设备退出该区域时的回调
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region;
// Monitoring有错误产生时的回调
- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(nullable CLRegion *)region withError:(NSError *)error;
复制代码
Ranging:能够用来检测某区域内的全部 iBeacons。
// 开始检测区域
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
// 中止检测区域
[self.locationManager stopRangingBeaconsInRegion:beaconRegion];
// Ranging成功对应回调函数
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray<CLBeacon *> *)beacons inRegion:(CLBeaconRegion *)region
// Ranging有错误产生时的回调
- (void)locationManager:(CLLocationManager *)manager rangingBeaconsDidFailForRegion:(CLBeaconRegion *)region withError:(NSError *)error
复制代码
// 当程序被杀掉以后,进入ibeacon区域,或者在程序运行时锁屏/解锁 会回调此函数
- (void)locationManager:(CLLocationManager *)manager
didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
复制代码
必要时,可使用UIApplication
类的- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void (^)(void))handler;
方法,请求更多的后台执行时间。
任何支持使用蓝牙低功耗共享数据的 iOS 设备均可以用做 iBeacon
。
import <CoreBluetooth/CoreBluetooth.h>
和<CoreLocation/CoreLocation.h>
在terminal
中使用uuidgen
命令,生成一个 UUID 063FA845-F091-4129-937D-2A189A86D844
。
其实利用BLE
来模拟 beacon 设备发送信号,很简单。
初始化peripheralManager
self.peripheralManager= [[CBPeripheralManager alloc] initWithDelegate:self queue:nil options:nil];
复制代码
发送信号
NSUUID *proximityUUID = [[NSUUID alloc] initWithUUIDString:self.UUIDTextField.text];
//建立beacon区域
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:proximityUUID major:self.majorTextField.text.integerValue minor:self.minorTextField.text.integerValue identifier:@"test"];
NSDictionary *beaconPeripheraData = [beaconRegion peripheralDataWithMeasuredPower:nil];
if(beaconPeripheraData) {
[self.peripheralManager startAdvertising:beaconPeripheraData];;//开始广播
}
复制代码
中止广播
[self.peripheralManager stopAdvertising];
复制代码