[英]How to know the closest iBeacon
我有一个代码知道哪个信标最接近,但是当信标的准确度为-1.00000时,我有一个问题,应用程序采用第二个。
因此,有一个布鲁克寻求最近的灯塔寻找其他人,并将最接近的灯塔与周围的其他灯塔进行比较。 然后,当我知道哪个是最接近的那个时,我向用户显示它的视图,但是当其他信标靠近ipad时,视图关闭并且显示视图。
我在iPad上使用iOS 7.1和7.0.4,首先是iPad3,第二个是iPad Mini Retina。
在这里你有代码:
- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region {
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}
- (void)initRegion {
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:@"00000000-0000-0000-0000-000000000002"];
self.beaconRegion = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:@"com.devfright.myRegion"];
[self.locationManager startMonitoringForRegion:self.beaconRegion];
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
NSLog(@"Beacon Found");
[self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
NSLog(@"Left Region");
[self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
}
-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region {
CLBeacon *beacon = [[CLBeacon alloc] init];
CLBeacon *closestBeacon = [[CLBeacon alloc] init];
closestBeacon = [beacons lastObject];
//Search for the closest and show the view
for (int i=0; i<beacons.count; i++) {
beacon = beacons[i];
if (beacon.accuracy < closestBeacon.accuracy && beacon.accuracy != -1.000000 && beacon.minor != closestBeacon.minor && beacon.proximity != CLProximityFar) {
closestBeacon = beacons[i];
//NSString *closeAccuracy = closestBeacon.minor.stringValue;
}
NSLog(@"\nActualBeacon:%@\nAccuracy:%f", beacon.minor.stringValue,beacon.accuracy);
NSLog(@"\nCloserBeacon: %@\nAccuracy:%f", closestBeacon.minor.stringValue, closestBeacon.accuracy);
}
NSLog(@"\nClosestBeacon: %@", closestBeacon.minor.stringValue);
if (viewShown == NO) {
if ([closestBeacon.minor.stringValue isEqual: @"1"]) {
actualSection = 1;
[self immediateDetection];
}else if ([closestBeacon.minor.stringValue isEqual: @"2"]){
actualSection = 2;
[self immediateDetection];
}else if ([closestBeacon.minor.stringValue isEqual: @"3"]){
actualSection = 3;
[self immediateDetection];
}else if ([closestBeacon.minor.stringValue isEqual: @"4"]){
actualSection = 4;
[self immediateDetection];
}else if ([closestBeacon.minor.stringValue isEqual: @"5"]){
actualSection = 5;
[self immediateDetection];
}else if ([closestBeacon.minor.stringValue isEqual: @"6"]){
actualSection = 6;
[self immediateDetection];
NSLog(@"6");
}else if ([closestBeacon.minor.stringValue isEqual: @"7"]){
actualSection = 7;
[self immediateDetection];
NSLog(@"7");
}else if ([closestBeacon.minor.stringValue isEqual: @"8"]){
actualSection = 8;
[self immediateDetection];
NSLog(@"8");
}else if ([closestBeacon.minor.stringValue isEqual: @"9"]){
actualSection = 9;
[self immediateDetection];
NSLog(@"9");
}else if ([closestBeacon.minor.stringValue isEqual: @"10"]){
actualSection = 10;
[self immediateDetection];
NSLog(@"10");
}else if ([closestBeacon.minor.stringValue isEqual: @"11"]){
actualSection = 11;
[self immediateDetection];
NSLog(@"11");
}else if ([closestBeacon.minor.stringValue isEqual: @"30"]){
actualSection = 30;
[self immediateDetection];
}
} else if (viewShown == YES) {
if (closestBeacon.minor.integerValue != actualSection) {
//Alarm: Beacon 11
// if (closestBeacon.minor.integerValue != 11 || closestBeacon.minor.integerValue != 10) {
[self dismissViewControllerAnimated:NO completion:nil];
//actualSection = 0;
viewShown = NO;
// }
}
}
}
- (void)immediateDetection
{
viewShown = YES;
if (self.presentedViewController)
{
return;
}
if (actualSection == 1) {
SectionViewController *sectionView = [[SectionViewController alloc] init];
sectionView.section = 1;
[self presentViewController:sectionView animated:NO completion:nil];
sectionView.lbl_name.text = self.lbl_name.text;
}else if (actualSection == 2){
SectionViewController *sectionView = [[SectionViewController alloc] init];
sectionView.section = 2;
[self presentViewController:sectionView animated:NO completion:nil];
sectionView.lbl_name.text = self.lbl_name.text;
}else if (actualSection == 3){
SectionViewController *sectionView = [[SectionViewController alloc] init];
sectionView.section = 3;
[self presentViewController:sectionView animated:NO completion:nil];
sectionView.lbl_name.text = self.lbl_name.text;
}else if (actualSection == 4){
SectionViewController *sectionView = [[SectionViewController alloc] init];
sectionView.section = 4;
[self presentViewController:sectionView animated:NO completion:nil];
sectionView.lbl_name.text = self.lbl_name.text;
}else if (actualSection == 5){
SectionViewController *sectionView = [[SectionViewController alloc] init];
sectionView.section = 5;
[self presentViewController:sectionView animated:NO completion:nil];
sectionView.lbl_name.text = self.lbl_name.text;
}else if (actualSection == 6){
SectionViewController *sectionView = [[SectionViewController alloc] init];
sectionView.section = 6;
[self presentViewController:sectionView animated:NO completion:nil];
sectionView.lbl_name.text = self.lbl_name.text;
}else if (actualSection == 7){
SectionViewController *sectionView = [[SectionViewController alloc] init];
sectionView.section = 7;
[self presentViewController:sectionView animated:NO completion:nil];
sectionView.lbl_name.text = self.lbl_name.text;
}else if (actualSection == 8){
SectionViewController *sectionView = [[SectionViewController alloc] init];
sectionView.section = 8;
[self presentViewController:sectionView animated:NO completion:nil];
sectionView.lbl_name.text = self.lbl_name.text;
}else if (actualSection == 9){
SectionViewController *sectionView = [[SectionViewController alloc] init];
sectionView.section = 9;
[self presentViewController:sectionView animated:NO completion:nil];
sectionView.lbl_name.text = self.lbl_name.text;
}else if (actualSection == 10){
ThiefAlarmViewController *thiefAlarmView = [[ThiefAlarmViewController alloc] init];
[self presentViewController:thiefAlarmView animated:NO completion:nil];
}else if (actualSection == 11){
ThiefAlarmViewController *thiefAlarmView = [[ThiefAlarmViewController alloc] init];
[self presentViewController:thiefAlarmView animated:NO completion:nil];
}else if (actualSection == 30){
SectionViewController *sectionView = [[SectionViewController alloc] init];
sectionView.section = 30;
[self presentViewController:sectionView animated:NO completion:nil];
sectionView.lbl_name.text = self.lbl_name.text;
}
}
当我知道最接近的iBeacon时,我会显示它的视图,但是当它的准确度为-1.00000并且与其他人相比时,应用程序采用第二个,因为第一个具有准确度= -1.00000。
希望任何人都可以帮助我,因为我不知道该怎么做,也许这是一个iBeacon问题,但我认为这个问题有一个解决方案。
谢谢。
locationManager:didRangeBeacons:inRegion:
将返回接近顺序的信标列表。 也就是说,列表中的第一个信标将是离您最近的。
但是,此规则有一个例外:如果任何信标接近未知,则它们将位于列表的顶部(因为它们的准确度为-1)。 为了解决这个问题,只需过滤掉任何未知信标,然后选择列表中的第一个:
beacons = [beacons filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"proximity != %d", CLProximityUnknown]];
CLBeacon *nearestBeacon = [beacons firstObject];
首先:替换你的long else/if
of locationManager:didRangeBeacons:inRegion:
with:
if (([closestBeacon.minor intValue] > 0 && [closestBeacon.minor intValue] <= 11) || [closestBeacon.minor intValue] == 30)
{
actualSection = [closestBeacon.minor intValue];
[self immediateDetection];
}
用immediateDetection
替换你的long else/if
:
if ((actualSection > 0 && actualSection < 10 || actualSection == 30)
{
SectionViewController *sectionView = [[SectionViewController alloc] init];
sectionView.section = actualSection;
[self presentViewController:sectionView animated:NO completion:nil];
sectionView.lbl_name.text = self.lbl_name.text;
}
else if (actualSection == 10 || actualSection == 11)
{
ThiefAlarmViewController *thiefAlarmView = [[ThiefAlarmViewController alloc] init];
[self presentViewController:thiefAlarmView animated:NO completion:nil];
}
else
{
}
这应该可以为您节省大量代码。
对于您的问题,您可以这样:
NSPredicate *predicateIrrelevantBeacons = [NSPredicate predicateWithFormat:@"(self.accuracy != -1) AND ((self.proximity != %d) OR (self.proximity != %d))", CLProximityFar,CLProximityUnknown];
NSArray *relevantsBeacons = [beacons filteredArrayUsingPredicate: predicateIrrelevantBeacons];
NSPredicate *predicateMin = [NSPredicate predicateWithFormat:@"self.accuracy == %@.@min.accuracy", relevantsBeacons];
CLBeacon *closestBeacon = nil;
NSArray *closestArray = [[relevantsBeacons filteredArrayUsingPredicate:predicateMin];
if ([closestArray count] > 0)
closestBeacon = [closestArray objectAtIndex:0];
if (closestBeacon)
{ //Do your thing }
else
{//No relevant close beacon}
除了过滤接近值-1之外,还必须考虑某些iBeacons定期不出现在didRangeBeacons: inRegion
的回调中的didRangeBeacons: inRegion
。 这可能是由于无线电干扰而发生的,特别是对于不经常传输广告的电池供电的信标。
要解决此问题,您需要保留自己最近看过的信标列表,并跟踪过去几秒钟内看到的任何信标。 如果其中一个信标的接近度为-1,则可以不将其放在列表中,或者如果不存在,则重新使用上一个已知的非-1接近值。
您需要考虑的另一个考虑因素是接近值会在很大程度上反弹。 您可能需要为算法添加一些滞后逻辑,以便最接近的信标不会每秒来回反弹。 您希望如何执行此操作的具体细节取决于您的用例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.