1、簡介
iBeacon設備是基於藍牙進行廣播的,通過發送廣播信號,附近的用戶當進入到設備附近的範圍區域,即可通過手機與之交互。在iOS開發中,要讓iBeacon設備與手機交互開發不是使用CoreBlueTooth庫提供的API,而是CoreLocation庫,具體來說用的類有CLLocationManager、CLBeaconRegion和CLBeacon類。
2、開發要點
- 用戶權限
開發iBeacon,需要用戶開啓定位權限,在筆者實際試驗中發現,用戶必須開啓“始終”權限。用戶選擇:“永不”和“在使用期間”都不行。具體代碼是調用:requestAlwaysAuthorization方法
常用流程
- 初始化CLLocationManager對象
- (CLLocationManager *)locationManager
{
if (!_locationManager) {
_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
}
return _locationManager;
}
- 初始化CLBeaconRegion對象,並且開啓區域掃描
CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:self.regionDictionary[key]] identifier:key];
// 調用startMonitoringForRegion後,
// 將執行代理方法;locationManager:didStartMonitoringForRegion
[self.locationManager startMonitoringForRegion:beaconRegion];
- 掃描後依次執行下面的代碼方法。
用戶調用requestStateForRegion後,就可以獲取掃描區域的狀態
#pragma mark - CLLocationMangerDelegate - ibeacom
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
{
// 調用requestStateForRegion後將執行代理方法:
// locationManager:didDetermineState:forRegion
[manager requestStateForRegion:region];
}
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
if ([region isKindOfClass:[CLBeaconRegion class]] && state == CLRegionStateInside) {
[self locationManager:manager didEnterRegion:region];
}
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region{
// when devie enter region
NSLog(@"didEnterRegion--->%@",region);
if (region.identifier.length != 0) {
if (@available(iOS 13.0, *)) {
// CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithUUID:[[NSUUID alloc] initWithUUIDString:self.regionDictionary[region.identifier]] identifier:region.identifier];
// [self.locationManager startRangingBeaconsInRegion:beaconRegion];
} else {
// Fallback on earlier versions
}
}
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
// when devie leave region
NSLog(@"didExitRegion--->%@",region);
if (region.identifier.length != 0) {
if (@available(iOS 13.0, *)) {
// CLBeaconRegion *beaconRegion = [[CLBeaconRegion alloc] initWithUUID:[[NSUUID alloc] initWithUUIDString:self.regionDictionary[region.identifier]] identifier:region.identifier];
// [self.locationManager stopRangingBeaconsInRegion:beaconRegion];
} else {
// Fallback on earlier versions
}
}
}
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray<CLBeacon *> *)beacons inRegion:(CLBeaconRegion *)region{
if (beacons.count>0) {
NSString *scanRst = @"";
self.myBeacon = beacons.firstObject;
if (@available(iOS 13.0, *)) {
// scanRst = self.myBeacon.UUID.UUIDString;
// NSLog(@"UUID:%@,major:%@,minor:%@",
// self.myBeacon.UUID.UUIDString,self.myBeacon.major,self.myBeacon.minor);
} else {
// Fallback on earlier versions
scanRst = self.myBeacon.proximityUUID.UUIDString;
NSLog(@"UUID:%@,major:%@,minor:%@",
self.myBeacon.proximityUUID.UUIDString,self.myBeacon.major,self.myBeacon.minor);
}
}
}
- (void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
{
}
上面的註釋描述了獲取iBeacon設備的UUID.APP獲取到UUID後進行一些業務的處理。
另外,APP可以通過下面的代理方法獲取用戶權限的變化。
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
switch (status) {
case kCLAuthorizationStatusNotDetermined:
NSLog(@"kCLAuthorizationStatusNotDetermined");
break;
case kCLAuthorizationStatusRestricted:
NSLog(@"kCLAuthorizationStatusNotDetermined");
break;
case kCLAuthorizationStatusDenied:
NSLog(@"kCLAuthorizationStatusDenied");
break;
case kCLAuthorizationStatusAuthorizedAlways:
NSLog(@"kCLAuthorizationStatusAuthorizedAlways");
break;
case kCLAuthorizationStatusAuthorizedWhenInUse:
NSLog(@"kCLAuthorizationStatusAuthorizedWhenInUse");
break;
default:
break;
}
}