iBeacon 介紹
iBeacon 是蘋果公司在 iOS7上配備的新功能,可以讓附近的手持電子裝置檢測到一個由一個 iBeacon 訊號發射器發出的藍芽訊號. 它採用了基於藍芽4.0的低功耗藍芽技術(Bluetooth Low Energy, BLE),主要是用作輔助室內定位的功能.
iBeacon 原理
iBeacon中有兩個角色:
發射者
: 一般都是各種硬體
接收者
: 一般都是智慧終端(手機)
發射者通過BLE 的廣告通訊通道,以一定時間間隔向外廣播資料包(一般是每秒兩三次),接收者可以通過終端提供的功能來接收,達到資訊的互動.
每個訊號中至少攜帶了三個主要資訊:UUID
, Major
, Minor
,這三個訊號組成了一個 iBeacon 的唯一識別符號.
當 iOS裝置接收到 iBeacon 訊號時,還會有其他重要資訊:
rssi: 訊號強度
proximity: 發射者到接收者的距離(不是數值,是個列舉: Unknow, Immediate, Near, Far)
accuracy: 水平精度
其實,發射者也就是硬體向四周不停地廣播訊號,而訊號就像是水波一樣像四周擴散,越靠近中心點的水波越高也就是 rssi 訊號越強,而一旦有東西阻隔,訊號就會減弱甚至消失,而且一旦超過一定值,訊號就會消失,這說明 iBeacon 的廣播範圍是有限的.
說完發射者,再來說接收者. 接收者提供了兩種方式來接收iBeacon訊號:
Monitoring
: 可以用來在裝置進入/退出某個地理區域時獲得通知, 使用這種方法可以在應用程式的後臺執行時檢測iBeacon,但是隻能同時檢測20個region區域,並且不能夠推測裝置與iBeacon的距離.Ranging
: iOS 7之後提供的 API, 用於確定裝置的近似距離iBeacon 技術,可以用來檢測某區域內的所有iBeacons,並且可以精度估計發射者與接收者的距離,這個使用如下四中接近狀態來表示:
相關 API
終於說到 API, 這個是可能踩坑比較多的地方了.
- 需要開啟 GPS 定位和藍芽.
- iBeacon 的 API 是在 CoreLocation, 但iBeacon 必須要開啟藍芽,如果需要判斷藍芽,需要用到 CoreBluetooth 框架.
- Monitoring和 Ranging 是兩種監測方式,可以一起用,但是需要區分業務需求,兩種一起用會有小坑.
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self; // 遵循代理
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
// 請求使用者授權定位許可權
[self.locationManager requestAlwaysAuthorization];
}
複製程式碼
CLBeaconRegion 的建立
CLBeaconRegion *region = [[CLBeaconRegion alloc]initWithProximityUUID:#UUID# identifier: #identifier#];
region.notifyOnExit = YES;
region.notifyOnEntry = YES;
region.notifyEntryStateOnDisplay = YES;
複製程式碼
接下來是兩種方式監測 iBeacon 方式:
// Monitoring
// 開始檢測區域
[self.locationManager startMonitoringForRegion:beaconRegion];
// 停止檢測區域
[self.locationManager stopMonitoringForRegion:beaconRegion];
// delegate
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
// 裝置進入該區域時的回撥
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
// 裝置退出該區域時的回撥
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
// 有錯誤產生時的回撥
- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(nullable CLRegion *)region withError:(NSError *)error
複製程式碼
// Ranging
// 開始檢測區域
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
// 停止檢測區域
[self.locationManager stopRangingBeaconsInRegion:beaconRegion];
// delegate
// 檢測到區域內的iBeacons的回撥函式,包含監測到的所有 iBeacon 的資訊
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray<CLBeacon *> *)beacons inRegion:(CLBeaconRegion *)region
// 有錯誤產生時的回撥
- (void)locationManager:(CLLocationManager *)manager rangingBeaconsDidFailForRegion:(CLBeaconRegion *)region withError:(NSError *)error
複製程式碼
注意事項(坑點)
- Monitoring和Ranging最好不要一起用,會莫名其妙出現這樣的 log:
[Client] {"msg":"Fence: onClientEventRegionState, invalid state", "regionState":"0"}
複製程式碼
google也搜不到why,在後來我關掉Monitoring再也沒有出現這個 log.
- iBeacon 這個功能的 API 是在 CoreLocation 框架, 但是 iBeacon 必須要開啟藍芽,不然會一直失敗, 藍芽又要用到 CoreBluetooth 來監聽狀態.(....)
參考
---如果你有興趣, 請直接去這裡: developer.apple.com/ibeacon/Get… medium.com/@jerrywang0…