ibeacon使用(一)基础功能

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

background fetch.png
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

你可能感兴趣的:(ibeacon使用(一)基础功能)