iBeacon
是蘋果公司2013年9月發佈的移動設備用OS(iOS7)上配備的新功能。其工做方式是,配備有低功耗藍牙(BLE)通訊功能的設備使用BLE
技術向周圍發送本身特有的 ID,接收到該 ID 的應用軟件會根據該 ID 採起一些行動。html
從我的的角度看: iBeacon
向四面八方不停地廣播信號,就像是往平靜的水面上扔了一塊石子,泛起層層漣漪(俗稱水波),波峯至關於 iBeacon 的RSSI
(接受信號強度指示),越靠近中心點的地方波峯越高(RSSI 越大),這個波峯的大小(RSSI 的值)受到扔石子時用力大小(發射功率)和水質(周圍環境因子)的影響,離中心點越遠水波越趨向於平靜,超過了必定值,水波會消失於無形,也就是說 iBeacon 向外廣播的距離是有範圍的,超過了這個範圍,將接受不到 iBeacon 的信號。ios
從iOS開發者的角度看: iBeacon 在 CoreLocation
框架中抽象爲CLBeacon
類, 該類有6個屬性,分別是:git
proximityUUID
,是一個 NSUUID
,用來標識公司。每一個公司、組織使用的 iBeacon 應該擁有一樣的 proximityUUID
。github
major
,主要值,用來識別一組相關聯的 beacon,例如在連鎖超市的場景中,每一個分店的 beacon 應該擁有一樣的 major
。bash
minor
,次要值,則用來區分某個特定的 beacon。app
proximity
,遠近範圍的,一個枚舉值。框架
typedef NS_ENUM(NSInteger, CLProximity) {
CLProximityUnknown,// 無效
CLProximityImmediate,//在幾釐米內
CLProximityNear,//在幾米內
CLProximityFar//超過 10 米之外,不過在測試中超不過10米就是far
}
複製代碼
accuracy
,與iBeacon的距離。ide
rssi
,信號輕度爲負值,越接近0信號越強,等於0時沒法獲取信號強度。函數
Tip:proximityUUID
,major
,minor
這三個屬性組成 iBeacon
的惟一標識符。測試
只要進入iBeacon
的範圍,就能喚醒 App(大約10秒鐘),即便在程序被殺掉的狀況下。必要時,可使用UIApplication
類的- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void (^)(void))handler;
方法,請求更多的後臺執行時間。
iBeacon的用途:咱們能夠用iBeacon
能夠進行室內定位(車庫,商場),智能打卡,提醒(離開某物體的時候,好比離開家)。
iOS 中 iBeacon 是基於地理位置的微定位技術,雖然藉助手機藍牙進行接收Majro
、Minor
,可是他們在開發工程中沒有任何關係。
iBeacon
使用蘋果提供CoreLocation
庫,然而在 BLE 在開發過程當中使用CoreBluetooth
庫。從上面提供的庫來看就很清楚了,特別是在 iOS8.0 以後的時候若是想使用iBeacon
,必須讓用戶點擊是否容許XXapp
使用地理位置。若是在第一次使用 iOS App 掃描iBeacon
的時候沒有提示這句話,是不可能接收到iBeacon
的信號(除非iOS 8.0之下)。若是是 BLE 則的開發過程當中之須要提示用戶打開藍牙,並不要求其餘的地理位置任何信息。
在info.plist
中添加NSLocationAlwaysAndWhenInUseUsageDescription
,NSLocationWhenInUseUsageDescription
,NSLocationAlwaysUsageDescription
,請求地理位置權限。
開啓Background Modes
import <CoreLocation/CoreLocation.h>
。
初始化locationManager
和beaconRegion
。
- (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 區域檢測");
}
複製代碼
可用兩種方式檢測區域Monitoring
或Ranging
方式
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
複製代碼
// 當程序被殺掉以後,進入ibeacon區域,或者在程序運行時鎖屏/解鎖 會回調此函數
- (void)locationManager:(CLLocationManager *)manager
didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
複製代碼
必要時,可使用UIApplication
類的- (UIBackgroundTaskIdentifier)beginBackgroundTaskWithExpirationHandler:(void (^)(void))handler;
方法,請求更多的後臺執行時間。
任何支持使用藍牙低功耗共享數據的 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];
複製代碼