How to find your nearest iBeacon

I have a code to find out which beacon is closest, but I have a problem when the accuracy of the beacon is -1.00000, the application takes the second.

So, there is a handful that is looking for the nearest lighthouse looking for others, and comparing the nearest with others found around. Then, when I know which one is the closest, I show it to the user, but when the other beacon is closer to the ipad, the view closes and the view is displayed.

I use iOS 7.1 and 7.0.4 on 2 iPads, first iPad3, and the second - iPad Retina Retina.

Here you have the code:

    - (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;
    }
}

When I know the closest iBeacon, I show its appearance, but when its accuracy is -1.00000 and compared with others, the application takes the second, because the first has accuracy = -1.00000.

, - , , , , iBeacon, , .

.

+4
3

: else/if locationManager:didRangeBeacons:inRegion: :

if (([closestBeacon.minor intValue] > 0 && [closestBeacon.minor intValue] <= 11) || [closestBeacon.minor intValue] == 30)
{
    actualSection = [closestBeacon.minor intValue]; 
    [self immediateDetection];
}

else/if immediateDetection :

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}
+4

locationManager:didRangeBeacons:inRegion: . , .

: - , ( -1). , , :

beacons = [beacons filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"proximity != %d", CLProximityUnknown]];
CLBeacon *nearestBeacon = [beacons firstObject];
+4

-1, , iBeacons didRangeBeacons: inRegion. - , , .

, , . -1, , -, .

Another consideration you need to consider is that the value of proximity will be greatly distorted. You may need to add hysteresis logic to your algorithm, so that the nearest beacon does not bounce back and forth every second. The specifics of how you want to do this depends on your use case.

+3
source

Source: https://habr.com/ru/post/1538041/


All Articles