ibeacon介绍
ibeacon通过信号发射器发出蓝牙信号,用于定位技术,通过进出围栏的方法还可以做一些报警装置,本身是不支持使用蓝牙指令,可以结合蓝牙进行操作。
ibeacon的主要数据组成
UUID、Major、Minor、Rssi、Proximity、Accuracy。
UUID: 通用唯一标识符,这个是ibeacon设备的唯一标识,搜索ibeacon设备时需要用到,一般公司产品uuid是一致的,这个固定uuid就是他们的产品,再通过Major和Minor进行不同设备区分
Major: 主要值,2个字节,用来区分相关联的一组beacon设备
Minor: 次要值,2个字节,用来确定某个设备
Rssi: 信号强度,和蓝牙的rssi是一样的,负数,越接近于0信号越强
Accuracy: 与设备之间的距离
Proximity: 设备的远近范围,是个枚举值
typedef NS_ENUM(NSInteger, CLProximity) {
CLProximityUnknown,
CLProximityImmediate,
CLProximityNear,
CLProximityFar
} API_AVAILABLE(ios(7.0)) API_UNAVAILABLE(watchos, tvos);
major和minor不是必要的,可以用来携带一些信息,也可以用于确定唯一的设备。 ibeacon可以只靠uuid进行设备的确定,如果不知道自己设备的uuid、major和minor可以使用ibeacon扫描软件 (文末提供)
ibeacon使用
1. 导入头文件、添加定位权限
使用到定位的功能,需要导入CoreLocation框架、在info.plist中添加NSLocationAlwaysAndWhenInUseUsageDescription,NSLocationWhenInUseUsageDescription,NSLocationAlwaysUsageDescription,请求地理位置权限。
#import
开启Background Modes
2. 初始化locationManager和beaconRegion
- (id)init
{
if (self = [super init]) {
_locationManager = [[CLLocationManager alloc] init];
[_locationManager requestAlwaysAuthorization];
_locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
_locationManager.delegate = self;
//实时更新定位位置
_locationManager.distanceFilter = kCLDistanceFilterNone;
[_locationManager startUpdatingLocation];
NSUUID *estimoteUUID = [[NSUUID alloc] initWithUUIDString:ibeaconDeviceUUID];
if (@available(iOS 13.0, *)) {
_beaconRegion = [[CLBeaconRegion alloc] initWithUUID:estimoteUUID identifier:@""];
_beaconConstrait = [[CLBeaconIdentityConstraint alloc] initWithUUID:estimoteUUID];
}else{
_beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:estimoteUUID identifier:@""];
}
_beaconRegion.notifyEntryStateOnDisplay = YES;//locationManager:didDetermineState:forRegion:方法通知
_beaconRegion.notifyOnEntry = YES;//进入区域通知
_beaconRegion.notifyOnExit = YES;//退出区域通知
}
return self;
}
CLBeaconRegion的notifyEntryStateOnDisplay、notifyOnEntry、notifyOnExit要设置为YES,Monitoring和Ranging的主要代理回调都需要
CLBeaconRegion有四种初始化的方法,这里写的是iOS13提供的,iOS13以下的方法有三种和以下四种类似,根据不同的业务需求选择不同的监控方式。
//iOS13
//监控该UUID下的所有Beacon设备
- (instancetype)initWithUUID:(NSUUID *)uuid identifier:(NSString *)identifier API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, tvos, macos);
//监控该UUID、Major下的所有Beacon设备
- (instancetype)initWithUUID:(NSUUID *)uuid major:(CLBeaconMajorValue)major identifier:(NSString *)identifier API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, tvos, macos);
//监控该UUID、Major、Minor下的所有Beacon设备
- (instancetype)initWithUUID:(NSUUID *)uuid major:(CLBeaconMajorValue)major minor:(CLBeaconMinorValue)minor identifier:(NSString *)identifier API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, tvos, macos);
//监控CLBeaconIdentityConstraint参数下的所以Beacon设备(iOS13新增的和前三种方法类似,设置UUID、Major和Minor)
- (instancetype)initWithBeaconIdentityConstraint:(CLBeaconIdentityConstraint *)beaconIdentityConstraint identifier:(NSString *)identifier API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, tvos, macos);
iOS13新增的CLBeaconIdentityConstraint对象,封装用于设置uuid、Major和Minor,所以很多方法在iOS13中做了修改,本文主要是使用iOS13的方法,iOS13以下的方法基本相同
3. 设置监控
监控之前要先判断设备是否支持地理位置请求
- (void)checkMonitoringAuth
{
// 在开始监控之前,我们需要判断改设备是否支持,和区域权限请求
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:{
if (@available(iOS 13.0, *)) {
[self.locationManager startRangingBeaconsSatisfyingConstraint:self.beaconConstrait];
}else{
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}
[self.locationManager startMonitoringForRegion:self.beaconRegion];
}
break;
}
} else {
NSLog(@"该设备不支持 CLBeaconRegion 区域检测");
}
}
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
if (status == kCLAuthorizationStatusAuthorizedAlways
|| status == kCLAuthorizationStatusAuthorizedWhenInUse) {
if (@available(iOS 13.0, *)) {
[self.locationManager startRangingBeaconsSatisfyingConstraint:self.beaconConstrait];
}else{
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}
[self.locationManager startMonitoringForRegion:self.beaconRegion];
}
}
4.监控方式
有两种监听方式Monitoring或Ranging方式
-(void)startMonitoringForRegion:(CLRegion *)region API_AVAILABLE(ios(5.0), macos(10.8)) API_UNAVAILABLE(watchos, tvos);
- (void)startRangingBeaconsSatisfyingConstraint:(CLBeaconIdentityConstraint *)constraint API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, tvos, macos);
Monitoring
主要用于设备进入和退出某个地理区域会收到回调,可在后台运行时进行检查iBeacon,搭配蓝牙可实现很多功能,1个App最多能同时监控20个region
1.不能获取CLBeacon对象,也就不能读取到accuracy、rssi等数据 2.最好不要用于通过退出区域来判断iBeacon设备是否关闭,iBeacon设备关闭后,退出区域回调比较慢才收到
主要使用的方法是进入和离开区域,可在后台使用,可以用来唤醒App。
#pragma mark -- Monitoring
/** 进入区域 */
- (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 {
}
/** Monitoring 成功回调 */
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
}
Ranging
可以用来检测某区域内你所监控的iBeacons
//iOS13上的方法
/** 1秒钟执行1次 */ //进入和离开、点亮屏幕也会调这个方法
- (void)locationManager:(CLLocationManager *)manager
didRangeBeacons:(NSArray *)beacons
satisfyingConstraint:(CLBeaconIdentityConstraint *)beaconConstraint
{
for (CLBeacon *beacon in beacons) {
NSLog(@" rssi is :%ld",(long)beacon.rssi);
NSLog(@" beacon proximity :%ld",(long)beacon.proximity);
NSLog(@" accuracy : %f",beacon.accuracy);
NSLog(@" proximityUUID : %@",beacon.UUID.UUIDString);
NSLog(@" major :%ld",(long)beacon.major.integerValue);
NSLog(@" minor :%ld",(long)beacon.minor.integerValue);
}
}
/** ranging有错误产生时的回调 */
- (void)locationManager:(CLLocationManager *)manager
didFailRangingBeaconsForConstraint:(CLBeaconIdentityConstraint *)beaconConstraint
error:(NSError *)error{
}
Demo地址
本文的demo:ibeaconDemo
github上找的用于beacon扫描: BeaconScanner