接近 API 的不一致行为 - iOS iBeacon
Posted
技术标签:
【中文标题】接近 API 的不一致行为 - iOS iBeacon【英文标题】:Inconsistent behaviour by proximity API - iOS iBeacon 【发布时间】:2017-01-09 08:11:17 【问题描述】:我正在将 ios 设备转换为 iBeacon,然后使用核心位置的测距 API 来检测信标的接近度。现在,这可行,但我看到了一种不可预测的行为,有时在定义的距离(比如 10 米外)我看到没有信标,有时看到远信标,有时看到近信标。
有没有办法让这种行为更加一致?
- (void)viewDidLoad
[super viewDidLoad];
self.beaconSwitch.on = NO;
self.beaconView.backgroundColor = [UIColor clearColor];
self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:nil];
BeaconRegion *beaconRegion = [[BeaconRegion alloc] init];
self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:beaconRegion.uuid major:[beaconRegion.major shortValue] minor:[beaconRegion.minor shortValue] identifier:beaconIdentifier];
- (void)viewWillDisappear:(BOOL)animated
[super viewWillDisappear:animated];
[self.peripheralManager stopAdvertising];
- (IBAction)doneButtonPressed:(id)sender
[self dismissViewControllerAnimated:YES completion:nil];
- (IBAction)beaconSwitchPressed:(id)sender
if (self.beaconSwitch.on == true)
self.beaconView.beaconState = BNBeaconStateBroadcasting;
NSDictionary *data = [self.beaconRegion peripheralDataWithMeasuredPower:nil];
[self.peripheralManager startAdvertising:data];
else
self.beaconView.beaconState = BNBeaconStateStop;
[self.peripheralManager stopAdvertising];
以下是我将 iOS 设备转换为信标的方法:
这就是我如何接近它:
- (void)viewDidLoad
[super viewDidLoad];
BeaconRegion *beaconRegion = [[BeaconRegion alloc] init];
self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:beaconRegion.uuid identifier:beaconIdentifier];
self.beaconRegion.notifyOnEntry = YES;
self.beaconRegion.notifyOnExit = YES;
self.beaconRegion.notifyEntryStateOnDisplay = YES;
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.detectionSwitch.on = NO;
- (IBAction)beaconDetectionSwitchPressed:(id)sender
if (self.detectionSwitch.isOn)
[self.locationManager startMonitoringForRegion:self.beaconRegion];
[self.locationManager requestStateForRegion:self.beaconRegion];
else
self.lastProximity = CLProximityUnknown;
[self.locationManager stopMonitoringForRegion:self.beaconRegion];
[self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
self.titleLabel.text = @"";
self.messageLabel.text = @"";
- (void)viewWillDisappear:(BOOL)animated
[super viewWillDisappear:animated];
[self.locationManager stopMonitoringForRegion:self.beaconRegion];
[self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
self.locationManager = nil;
- (void)locationManager:(CLLocationManager *)iManager didEnterRegion:(CLRegion *)iRegion
NSLog(@"Detected a beacon");
if (![self.beaconRegion isEqual:iRegion])
return;
NSLog(@"Entered into the beacon region = %@", iRegion);
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
NSLog(@"Ranging beacon successful");
if (beacons.count > 0)
CLBeacon *nearestBeacon = beacons[0];
CLProximity currentProximity = nearestBeacon.proximity;
if (currentProximity == self.lastProximity)
NSLog(@"No Change in Beacon distance");
else
self.lastProximity = currentProximity;
[self updateUserAboutProximity];
else
self.lastProximity = CLProximityUnknown;
- (void)updateUserAboutProximity
NSString *title = @"--";
NSString *message = @"--";
switch (self.lastProximity)
case CLProximityUnknown:
title = @"No Beacon";
message = @"There is no nearby beacon";
break;
case CLProximityImmediate:
title = @"Immediate Beacon";
message = @"You are standing immediate to video wall!";
break;
case CLProximityNear:
if (self.isServerCallOn)
title = @"Near Beacon";
message = @"You are standing near to video wall!";
else
title = @"Near Beacon";
message = @"You are standing near to video wall! Initiating a server call.";
if (!self.ignoreSeverCallTrigger)
self.isServerCallOn = YES;
[self talkToServer];
else
NSLog(@"Ignoring server call trigger");
message = @"Ignoring server call trigger!";
break;
case CLProximityFar:
title = @"Far Beacon";
message = @"You are standing far from video wall!";
break;
default:
break;
self.titleLabel.text = title;
self.messageLabel.text = message;
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
if (state == CLRegionStateInside)
NSLog(@"Starting Ranging");
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
if (![CLLocationManager locationServicesEnabled])
NSLog(@"Location Service Not Enabled");
if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorizedAlways)
NSLog(@"Location Service Not Authorized");
【问题讨论】:
【参考方案1】:目前,我对接收信号强度指示器 (rssi) 值设置了一个条件,并在附近接受 > -60 的任何内容,以使距离更可预测。因此,如果 rssi > -60,我也会在 Nearby 附近触发我的操作。
【讨论】:
以上是关于接近 API 的不一致行为 - iOS iBeacon的主要内容,如果未能解决你的问题,请参考以下文章
C++ std::vector 乘法中是不是存在已知的不一致行为?
iOS7 中 jQuery Mobile 滑动事件的不稳定行为