iBeacon 介紹
iBeacon 是蘋果公司在 iOS7上配備的新功能,可以讓附近的手持電子設(shè)備檢測(cè)到一個(gè)由一個(gè) iBeacon 信號(hào)發(fā)射器發(fā)出的藍(lán)牙信號(hào).
它采用了基于藍(lán)牙4.0的低功耗藍(lán)牙技術(shù)(Bluetooth Low Energy, BLE),主要是用作輔助室內(nèi)定位的功能.
iBeacon 原理
iBeacon中有兩個(gè)角色:
發(fā)射者
: 一般都是各種硬件
接收者
: 一般都是智能終端(手機(jī))
發(fā)射者通過(guò)BLE 的廣告通信通道,以一定時(shí)間間隔向外廣播數(shù)據(jù)包(一般是每秒兩三次),接收者可以通過(guò)終端提供的功能來(lái)接收,達(dá)到信息的交互.
每個(gè)信號(hào)中至少攜帶了三個(gè)主要信息:UUID
, Major
, Minor
,這三個(gè)信號(hào)組成了一個(gè) iBeacon 的唯一標(biāo)識(shí)符.
當(dāng) iOS設(shè)備接收到 iBeacon 信號(hào)時(shí),還會(huì)有其他重要信息:
rssi: 信號(hào)強(qiáng)度
proximity: 發(fā)射者到接收者的距離(不是數(shù)值,是個(gè)枚舉: Unknow, Immediate, Near, Far)
accuracy: 水平精度
BLE 發(fā)射的是2.4GHz 的信號(hào),任何物理阻礙物都會(huì)影響 iBeacon 的信號(hào).
其實(shí),發(fā)射者也就是硬件向四周不停地廣播信號(hào),而信號(hào)就像是水波一樣像四周擴(kuò)散,越靠近中心點(diǎn)的水波越高也就是 rssi 信號(hào)越強(qiáng),而一旦有東西阻隔,信號(hào)就會(huì)減弱甚至消失,而且一旦超過(guò)一定值,信號(hào)就會(huì)消失,這說(shuō)明 iBeacon 的廣播范圍是有限的.
說(shuō)完發(fā)射者,再來(lái)說(shuō)接收者.
接收者提供了兩種方式來(lái)接收iBeacon信號(hào):
-
Monitoring
: 可以用來(lái)在設(shè)備進(jìn)入/退出某個(gè)地理區(qū)域時(shí)獲得通知, 使用這種方法可以在應(yīng)用程序的后臺(tái)運(yùn)行時(shí)檢測(cè)iBeacon臭挽,但是只能同時(shí)檢測(cè)20個(gè)region區(qū)域,并且不能夠推測(cè)設(shè)備與iBeacon的距離. -
Ranging
: iOS 7之后提供的 API, 用于確定設(shè)備的近似距離iBeacon 技術(shù),可以用來(lái)檢測(cè)某區(qū)域內(nèi)的所有iBeacons,并且可以精度估計(jì)發(fā)射者與接收者的距離,這個(gè)使用如下四中接近狀態(tài)來(lái)表示:
相關(guān) API
終于說(shuō)到 API, 這個(gè)是可能踩坑比較多的地方了.
- 需要打開(kāi) GPS 定位和藍(lán)牙.
- iBeacon 的 API 是在 CoreLocation, 但iBeacon 必須要打開(kāi)藍(lán)牙,如果需要判斷藍(lán)牙,需要用到 CoreBluetooth 框架.
- Monitoring和 Ranging 是兩種監(jiān)測(cè)方式,可以一起用,但是需要區(qū)分業(yè)務(wù)需求,兩種一起用會(huì)有小坑.
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self; // 遵循代理
if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
// 請(qǐng)求用戶授權(quán)定位權(quán)限
[self.locationManager requestAlwaysAuthorization];
}
CLBeaconRegion 的創(chuàng)建
CLBeaconRegion *region = [[CLBeaconRegion alloc]initWithProximityUUID:#UUID# identifier: #identifier#];
region.notifyOnExit = YES;
region.notifyOnEntry = YES;
region.notifyEntryStateOnDisplay = YES;
接下來(lái)是兩種方式監(jiān)測(cè) iBeacon 方式:
// Monitoring
// 開(kāi)始檢測(cè)區(qū)域
[self.locationManager startMonitoringForRegion:beaconRegion];
// 停止檢測(cè)區(qū)域
[self.locationManager stopMonitoringForRegion:beaconRegion];
// delegate
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
// 設(shè)備進(jìn)入該區(qū)域時(shí)的回調(diào)
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
// 設(shè)備退出該區(qū)域時(shí)的回調(diào)
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
// 有錯(cuò)誤產(chǎn)生時(shí)的回調(diào)
- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(nullable CLRegion *)region withError:(NSError *)error
// Ranging
// 開(kāi)始檢測(cè)區(qū)域
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
// 停止檢測(cè)區(qū)域
[self.locationManager stopRangingBeaconsInRegion:beaconRegion];
// delegate
// 檢測(cè)到區(qū)域內(nèi)的iBeacons的回調(diào)函數(shù),包含監(jiān)測(cè)到的所有 iBeacon 的信息
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray<CLBeacon *> *)beacons inRegion:(CLBeaconRegion *)region
// 有錯(cuò)誤產(chǎn)生時(shí)的回調(diào)
- (void)locationManager:(CLLocationManager *)manager rangingBeaconsDidFailForRegion:(CLBeaconRegion *)region withError:(NSError *)error
注意事項(xiàng)(坑點(diǎn))
- Monitoring和Ranging最好不要一起用,會(huì)莫名其妙出現(xiàn)這樣的 log:
[Client] {"msg":"Fence: onClientEventRegionState, invalid state", "regionState":"0"}
google也搜不到why,在后來(lái)我關(guān)掉Monitoring再也沒(méi)有出現(xiàn)這個(gè) log.
- iBeacon 這個(gè)功能的 API 是在 CoreLocation 框架, 但是 iBeacon 必須要打開(kāi)藍(lán)牙,不然會(huì)一直失敗, 藍(lán)牙又要用到 CoreBluetooth 來(lái)監(jiān)聽(tīng)狀態(tài).(....)
參考
---如果你有興趣, 請(qǐng)直接去這里:
https://developer.apple.com/ibeacon/Getting-Started-with-iBeacon.pdf
https://medium.com/@jerrywang0420/ibeacon-%E6%95%99%E5%AD%B8-swift-3-ios-1d4ea88311be