当前位置: 首页 > news >正文

iOS 中 iBeacon 开发

什么是iBeacon?

iBeacon 是苹果公司2013年9月发布的移动设备用OS(iOS7)上配备的新功能。其工作方式是,配备有低功耗蓝牙(BLE)通信功能的设备使用BLE技术向周围发送自己特有的 ID,接收到该 ID 的应用软件会根据该 ID 采取一些行动。

从个人的角度看: iBeacon向四面八方不停地广播信号,就像是往平静的水面上扔了一块石子,泛起层层涟漪(俗称水波),波峰相当于 iBeacon 的RSSI(接受信号强度指示),越靠近中心点的地方波峰越高(RSSI 越大),这个波峰的大小(RSSI 的值)受到扔石子时用力大小(发射功率)和水质(周围环境因子)的影响,离中心点越远水波越趋向于平静,超过了一定值,水波会消失于无形,也就是说 iBeacon 向外广播的距离是有范围的,超过了这个范围,将接受不到 iBeacon 的信号。

从iOS开发者的角度看: 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时无法获取信号强度。

Tip:proximityUUIDmajorminor 这三个属性组成 iBeacon 的唯一标识符。

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

iBeacon的用途:我们可以用iBeacon可以进行室内定位(车库,商场),智能打卡,提醒(离开某物体的时候,比如离开家)。

iBeacon 与 BLE 的区别

iOS 中 iBeacon 是基于地理位置的微定位技术,虽然借助手机蓝牙进行接收MajroMinor,但是他们在开发工程中没有任何关系。

iBeacon使用苹果提供CoreLocation库,然而在 BLE 在开发过程中使用CoreBluetooth库。从上面提供的库来看就很清楚了,特别是在 iOS8.0 之后的时候如果想使用iBeacon,必须让用户点击是否允许XXapp使用地理位置。如果在第一次使用 iOS App 扫描iBeacon的时候没有提示这句话,是不可能接收到iBeacon的信号(除非iOS 8.0之下)。如果是 BLE 则的开发过程中之需要提示用户打开蓝牙,并不要求其他的地理位置任何信息。

iBeacon 在 iOS 中的运用

权限请求

info.plist中添加NSLocationAlwaysAndWhenInUseUsageDescription,NSLocationWhenInUseUsageDescriptionNSLocationAlwaysUsageDescription,请求地理位置权限。

开启Background Modes

相关代码

import <CoreLocation/CoreLocation.h>

初始化locationManagerbeaconRegion

- (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 区域检测");
}
复制代码

监听方式

可用两种方式检测区域MonitoringRanging方式

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
复制代码

进程 kill 之后,进入 iBeacon 区域的回调

// 当程序被杀掉之后,进入ibeacon区域,或者在程序运行时锁屏/解锁 会回调此函数
- (void)locationManager:(CLLocationManager *)manager
      didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
复制代码

争取更多的后台时间

必要时,可以使用UIApplication类的- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void (^)(void))handler;方法,请求更多的后台执行时间。

用 iPhone 手机模拟 iBeacon

任何支持使用蓝牙低功耗共享数据的 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];
复制代码

注意点

  • 需要访问地理位置权限。
  • 设备需要开启蓝牙。
  • 利用 iOS 设备模拟 beacon信号,Home 出去之后是不能发送信号的。

Demo

官方 Demo

Blog Demo

参考文章

  • Apple 官方文档
  • iOS 中 iBeacon 总结
  • iBeacon工作原理
  • 在ios 的开发中 iBeacon 和 BLE 的区别

相关文章:

  • Kali-linux控制Meterpreter
  • HTTP响应状态码
  • 开源中文分词工具探析(六):Stanford CoreNLP
  • 用脚本模式配置数据同步
  • 如何在ubuntu16上安装docker
  • saltstack自动化运维系列④之saltstack的命令返回结果mysql数据库写入
  • 边车容器下的服务网格istio
  • Git基本
  • 【个人向】《HTTP图解》阅后小结
  • complexType
  • JAVA利用HttpClient进行POST请求(HTTPS)
  • 关于terracotta在tomcat集群中做session共享的问题
  • JAVA生成微信JSSDK接口签名
  • 工作总结-发送修改数据的请求时,修改数据成功,但是报非安全https请求,响应失败...
  • 陈松松:一个视频如何获得不同视频网站的排名秘诀
  • [译]前端离线指南(上)
  • Apache的80端口被占用以及访问时报错403
  • C++入门教程(10):for 语句
  • create-react-app项目添加less配置
  • JS数组方法汇总
  • laravel with 查询列表限制条数
  • linux学习笔记
  • log4j2输出到kafka
  • ReactNativeweexDeviceOne对比
  • vue中实现单选
  • 创建一种深思熟虑的文化
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 从重复到重用
  • 分享一份非常强势的Android面试题
  • 利用jquery编写加法运算验证码
  • 前端工程化(Gulp、Webpack)-webpack
  • 深度学习中的信息论知识详解
  • 什么软件可以剪辑音乐?
  • 视频flv转mp4最快的几种方法(就是不用格式工厂)
  • 我建了一个叫Hello World的项目
  • 优化 Vue 项目编译文件大小
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • #在线报价接单​再坚持一下 明天是真的周六.出现货 实单来谈
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (Matlab)基于蝙蝠算法实现电力系统经济调度
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
  • (算法)Travel Information Center
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级
  • (转)shell中括号的特殊用法 linux if多条件判断
  • ***检测工具之RKHunter AIDE
  • .NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions
  • .NET Core 实现 Redis 批量查询指定格式的Key
  • .NET 将混合了多个不同平台(Windows Mac Linux)的文件 目录的路径格式化成同一个平台下的路径
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • @Autowired多个相同类型bean装配问题
  • [ 常用工具篇 ] POC-bomber 漏洞检测工具安装及使用详解
  • [2019.3.20]BZOJ4573 [Zjoi2016]大森林