那一天我二十一岁,在我一生的黄金时代。我有好多奢望。我想爱,想吃,还想再一瞬间变成天上半明半暗的云。我来我才知道,生活就是个缓慢受锤的过程,人一天天老下去,奢望也一天天消失,最后变得像挨了锤的牛一样。可是我过二十一岁生日时没有预见到这一点。我觉得自己会永远生猛下去,什么也锤不了我。
——王小波《黄金时代》
前言
照例,如果只是需要监听iBeacon的demo代码,可以直接点击下载,不需要往下看了😂
如果想了解iBeacon相关信息,请参考iOS蓝牙开发之iBeacon篇(一)
- 虽然iBeacon也是基于Ble的,从硬件上看也是一套东西,但是Apple公司把他封装成了两套东西,所以在iOS移动端开发来说,这是两个完全不同的东西,调用完全不同框架的api.
- Apple公司为了省电和隐私限制只能监听指定UUID的iBeacon,无法像安卓一样搜索附近所有的iBeacon信息,虽然iBeacon扫描底层可以获取到附近的所有的iBeacon信息(底层就是获取附近所有的iBeacon然后和当前监听的iBeacon标识对比,然后回调给上层),如果你只是想在你自己的手机上测试下,可以参考AnyiBeacon-iOS这个项目,但是只能作为测试使用,因为涉及到Apple的私有api,是不允许上架App Store的。
- 想了解iBeacon底层数据协议格式的,可以参考What is the iBeacon Bluetooth Profile 这篇文章。
初始化
- 在 iOS8.0之后的时候如果想使用iBeacon,必须让用户授权
- 在info.plist文件里面配置下面的key
1 | NSLocationAlwaysAndWhenInUseUsageDescription // 推荐 |
- 在capabilities里面开启Background Modes的
Location updates
- 由于iBeacon是基于CoreLocation框架的,所以先导入头文件并实例化位置管理者
1 | import CoreLocation |
- 请求授权并设置代理
1 | override func viewDidLoad() |
添加需要监听的iBeacon
- 这个是添加iBeacon信息界面代理回调
1 | // MARK: AddBeacon |
- Item为一个iBeacon信息的数据模型, 即包含如下信息
1 | let name: String // 非必须 |
开始监听和停止监听
- 根据一个iBeacon的参数(iBeacon硬件提供或者自己用iPhone或者mac模拟)初始化一个CLBeaconRegion
- 两种监听模式
1 | func startMonitoring(_ item: Item) |
- 如果想停止监听某个iBeacon
1 | func stopMonitoring(_ item: Item) |
监听到iBeacon信息回调
- 开始监听某个Beacon
1 | func locationManager(_ manager: CLLocationManager, didStartMonitoringFor region: CLRegion) |
- 监听到Beacons
1 | // MARK: CLLocationManagerDelegate |
- 其他的回调方法
注意:
- 如果需要监听进入某个区域或者从某个区域离开,则需要在初始化Beacon Region的时候订阅
不然进入和离开区域不回回调
1
2> region.notifyOnEntry = YES;
> region.notifyOnExit = YES;
1 | // monitoring 监听某个beacon失败 |
关于推送
- app现在能显示iBeacon设备,并且还能实时监控它们的距离。但是当app没有处于运行状态时,如iBeacon设备在宠物猫脖子上但是宠物猫跑丢了!
- 此时app就需要在猫离开区域的时候通知用户。
- 在AppDelegate导入通知框架并初始化一个位置管理者
1 | import CoreLocation |
- 程序启动的时候,配置位置监听和设置通知
1 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { |
- 监听目标离开区域并发送本地通知
1 | extension AppDelegate: CLLocationManagerDelegate |
参考
官方文档
维基百科
iOS 中 iBeacon 开发
iBeacon Tutorial with iOS and Swift
How to detect ibeacon device without knowing UUID in iOS?
Detecting beacons via iBeacon Monitoring & Ranging vs CoreBluetooth scanForPeripheralsWithServices