iBeacon詳細介紹以及坑點

一銘發表於2017-12-13

iBeacon 介紹

iBeacon 是蘋果公司在 iOS7上配備的新功能,可以讓附近的手持電子裝置檢測到一個由一個 iBeacon 訊號發射器發出的藍芽訊號. 它採用了基於藍芽4.0的低功耗藍芽技術(Bluetooth Low Energy, BLE),主要是用作輔助室內定位的功能.

iBeacon 原理

iBeacon中有兩個角色: 發射者: 一般都是各種硬體 接收者: 一般都是智慧終端(手機) 發射者通過BLE 的廣告通訊通道,以一定時間間隔向外廣播資料包(一般是每秒兩三次),接收者可以通過終端提供的功能來接收,達到資訊的互動. 每個訊號中至少攜帶了三個主要資訊:UUID, Major, Minor,這三個訊號組成了一個 iBeacon 的唯一識別符號.

Beacon.png

當 iOS裝置接收到 iBeacon 訊號時,還會有其他重要資訊: rssi: 訊號強度 proximity: 發射者到接收者的距離(不是數值,是個列舉: Unknow, Immediate, Near, Far) accuracy: 水平精度

距離遠時.png

距離近時.png
BLE 發射的是2.4GHz 的訊號,任何物理阻礙物都會影響 iBeacon 的訊號.
block.png

其實,發射者也就是硬體向四周不停地廣播訊號,而訊號就像是水波一樣像四周擴散,越靠近中心點的水波越高也就是 rssi 訊號越強,而一旦有東西阻隔,訊號就會減弱甚至消失,而且一旦超過一定值,訊號就會消失,這說明 iBeacon 的廣播範圍是有限的.


說完發射者,再來說接收者. 接收者提供了兩種方式來接收iBeacon訊號:

  • Monitoring: 可以用來在裝置進入/退出某個地理區域時獲得通知, 使用這種方法可以在應用程式的後臺執行時檢測iBeacon,但是隻能同時檢測20個region區域,並且不能夠推測裝置與iBeacon的距離.
  • Ranging: iOS 7之後提供的 API, 用於確定裝置的近似距離iBeacon 技術,可以用來檢測某區域內的所有iBeacons,並且可以精度估計發射者與接收者的距離,這個使用如下四中接近狀態來表示:

proximity.png

相關 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…

相關文章