iOS iBeacon 使用(转)

66 阅读4分钟

1、什么是iBeacon?

 iBeacon 是苹果公司在 iOS 7 中新推出的一种近场定位技术,可以感知一个附近的 iBeacon 信标的存在。

当一个 iBeacon 兼容设备进入/退出一个 iBeacon 信标标识的区域时,iOS 和支持 iBeacon 的 app 就能得知这一信息,从而对用户发出相应的通知。

典型的应用场景例如博物馆实时推送附近展品的相关信息,商场内即时通知客户折扣信息等。苹果在 Apple Store 中也部署了 iBeacon 来推送优惠、活动信息。还可以应用的使用场景是将某个 iBeacon 发射器安装在你的电脑包、钱包甚至是你的猫的项圈上——即任何你不想丢失的重要物件。一旦你的设备离开发射器的范围,你的应用就会检测到并通知你。

2、UUID、主要、次要标识符

iBeacon 本质上来说是一个位置(区域)信息,所以 Apple 把 iBeacon 功能集成在了 Core Location 里面。
iBeacon 信标在 Core Location 中表现为一个 CLBeacon,它圈定的范围则表现为 CLBeaconRegion,这是一个 CLRegion 的子类。

CLBeaconRegion 主要用三个属性来标识一个 iBeacon,proximityUUIDmajor 和 minor

iBeacon 在 CoreLocation 框架中抽象为CLBeacon类, 该类有6个属性,分别是:

  • proximityUUID,是一个 NSUUID,用来标识公司。每个公司、组织使用的 iBeacon 应该拥有同样的 proximityUUID。

  • major,主要值,用来识别一组相关联的 beacon,例如在连锁超市的场景中,每个分店的 beacon 应该拥有同样的 major。

  • minor,次要值,则用来区分某个特定的 beacon。

  • proximity,远近范围的,一个枚举值。

    typedef NS_ENUM(NSInteger, CLProximity) {

    CLProximityUnknown,// 无效

    CLProximityImmediate,//在几厘米内

    CLProximityNear,//在几米内

    CLProximityFar//超过 10 米以外,不过在测试中超不过10米就是far

    }

  • accuracy,与iBeacon的距离。

  • rssi,信号轻度为负值,越接近0信号越强,等于0时无法获取信号强度。

这些属性如果不指定(即 nil),匹配的时候就会忽略这个属性。例如只指定 proximityUUID 的 CLBeaconRegion 可以匹配某公司的所有 beacons。

只要进入iBeacon的范围,就能唤醒 App(大约10秒钟),即使在程序被杀掉的情况下。必要时,可以使用UIApplication类的- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void (^)(void))handler;方法,请求更多的后台执行时间。

3、使用iOS设备作为iBeacon

如果手头没有iBeacon设备,任何支持蓝牙低功耗的IOS设备都可以作为iBeacon。

1.初始化peripheralManager

self.peripheralManager = [[CBPeripheralManageralloc] initWithDelegate:selfqueue:dispatch_get_main_queue() options:@{}];

 

CLBeaconRegion *beaconRegion = [[CLBeaconRegionalloc] initWithProximityUUID:[[NSUUIDalloc] initWithUUIDString:Beacon_Device_UUID] major:9999 minor:8888 identifier:@"0000"];

 

2.实现代理协议

  • (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {

    NSLog(@"didUpdateState: peripheralState=%ld", (long)peripheral.state);

    

    if (peripheral.state == CBManagerStatePoweredOn) {

        [self hopPayload];

    }

 

}

 

  • (void)hopPayload {

    if ([self.peripheralManagerisAdvertising]) {

        [self.peripheralManagerstopAdvertising];

    }

    NSDictionary *beaconPeripheraData = [self.beaconRegion11 peripheralDataWithMeasuredPower:@(-50)];

    [_peripheralManager startAdvertising:beaconPeripheraData];

 

}

 

**

 

3、相关代码

请求用户授权 (需要在info.plist文件中添加相关的权限 Privacy - Location Always Usage Description、Privacy - Location When In Use Usage Description、Privacy - Location Always and When In Use Usage Description)

引入 #import <CoreLocation/CoreLocation.h>  

 

NSString * const Beacon_Device_UUID = @"E2C56DB5-DFFB-48D2-B060-D0F5A71096E0";

**

*@property (strong, nonatomic) CLLocationManager locationManager;

*@property (strong, nonatomic) CLBeaconRegion beaconRegion;

 

1.判断用户权限

BOOL availableMonitor = [CLLocationManager isMonitoringAvailableForClass:[CLBeaconRegion class]];

if (availableMonitor) {

CLAuthorizationStatus authorizationStatus = [CLLocationManager authorizationStatus];

switch (authorizationStatus) {

case kCLAuthorizationStatusNotDetermined:

{

NSLog(@"这台设备可以检测到周围的beacon");

[self.locationManager requestAlwaysAuthorization];

}

break;

case kCLAuthorizationStatusRestricted:

case kCLAuthorizationStatusDenied:

NSLog(@"受限制或者拒绝");

break;

case kCLAuthorizationStatusAuthorizedAlways:

case kCLAuthorizationStatusAuthorizedWhenInUse:

[self startMonitoring];

break;

}

} else {

NSLog(@"该设备不支持 CLBeaconRegion 区域检测");

}

 

2.创建CLLocationManager对象

_locationManager = [[CLLocationManager alloc] init];

_locationManager.delegate = self;

 

3.创建圈定的范围区域对象CLBeaconRegion

_beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:Beacon_Device_UUID] identifier:@"test"];

根据需求用那种方式创建:

// 仅使用proximityUUID来初始化区域,major,minor值将作为通配符。只要是区域内的iBeacon的proximityUUID与此proximityUUID相同,不管major, minor是什么值,都能被检测到。

  • (instancetype)initWithProximityUUID:(NSUUID *)proximityUUID identifier:(NSString *)identifier;

//使用proximityUUID和major来初始化区域,minor值将作为通配符。区域内的iBeacon的proximityUUID和major与此proximityUUID和major相同时,不论minor为何值,都能被检测到。

 

  • (instancetype)initWithProximityUUID:(NSUUID *)proximityUUID major:(CLBeaconMajorValue)major identifier:(NSString *)identifier;

//使用proximityUUID, major, minor来初始化,只能检测到区域内相同proximityUUID, major, minor的iBeacon设备。

  • (instancetype)initWithProximityUUID:(NSUUID *)proximityUUID major:(CLBeaconMajorValue)major minor:(CLBeaconMinorValue)minor identifier:(NSString *)identifier;

 

4.可用两种方式检测区域 Monitoring或Ranging方式

第一种:

[self.locationManager startMonitoringForRegion:self.beaconRegion];

#pragma mark - Monitoring:可以用来在设备进入/退出某个地理区域时获得通知, 使用这种方法可以在应用程序的后台运行时检测 iBeacon,但是只能同时检测 20 个 region 区域,并且不能够推测设备与 iBeacon 的距离。

// Monitoring成功对应回调函数

*- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(nonnull CLRegion )region {

NSLog(@"Monitoring成功");

}

**

// Monitoring有错误产生时的回调

*- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(nullable CLRegion *)region withError:(nonnull NSError )error {

NSLog(@"Failed monitoring region: %@", error);

}

**

*- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError )error {

NSLog(@"Location manager failed: %@", error);

}

**

// 设备退出该区域时的回调

*- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion )region {

NSLog(@"设备出了你的范围了");

}

**

// 设备进入该区域时的回调

*- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion )region

{

NSLog(@"设备进入你的范围了");

*NSLog(@"******enter region:%@",region.identifier);

}

 第二种:

[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];

#pragma mark -- Ranging:可以用来检测某区域内的所有 iBeacons

//manager监测当前进入范围的beacon

*- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion )region {

}

 

GitHub地址:https://github.com/KunlunLu/BeaconDemo

 

也可参考:www.cocoachina.com/ios/2018021…

https://www.cnblogs.com/yangmx/p/3722795.html

原文链接:www.cnblogs.com/lukunlun/p/…