Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iBeacon monitoring and ranging in background

I took several months developing an application based on iBeacons and I'm really frustrated.

The general idea is that when a beacon is detected, the user is notified with information specific to that iBeacon.

The application was designed as follows, all iBeacons have the same UUID, the Major determines the building (Museum, shop...) and the Minor the specific product (pictures, shoes...). So this application may serve multiple clients.

When the application starts, I begin to do monitoring and ranging for region with our UUID. When the app is in foreground all works perfect. But in background or suspended state the problems starts. Ranging is not allowed on background or suspended state.

I know that the app will be launched into the background for about 5 seconds when you enter or exit the region of a beacon. You can here do ranging in the background for this five second period, after which iOS will suspend your app again.

I managed to extend ranging for up to 3 minutes in the background with the technique learned here. I also get an extra callback with notifyEntryStateOnDisplay = YES;

But this is not enough, if a client enters a region with the app in background or suspended state, he will be notified. And during the extra 3 minutes he will be notified if the ranging detects another iBeacon, but when the 3 minutes background task expired, if no region exit is triggered he will not receive any notification again.

Is there no real solution in a scenario like this? I think it is a very common scenario and I'm surprised no way to deal with it.

EDITED: I tried to find a solution to the problem by monitoring two regions as recommended David Young in his response. In order to obtain more events of entry/exit regions.

I added the code I implemented to try to monitor two regions.

but something I have done incorrectly and didRangeBeacons:InRegion: callback is firing every 10 ms when the expected is every second.

On AppDelegate.m, I'm doing the following inside didFinishLaunchingWithOptions:

[self.locationManager startMonitoringForRegion:self.beaconRegion];
        [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion];
        [self.locationManager startRangingBeaconsInRegion:self.beaconRegion];
        [self.locationManager startMonitoringForRegion:self.beaconRegion2];
        [self.locationManager stopRangingBeaconsInRegion:self.beaconRegion2];
        [self.locationManager startRangingBeaconsInRegion:self.beaconRegion2];

Then, on didRangeBeacons:InRegion:

- (void) locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region{

     if(beacons.count > 0){
          [self.locationManager stopRangingBeaconsInRegion:region];
          for (CLBeacon *beacon in beacons){
             NSLog(@"beacon detected major: %@ minor: %@", beacon.major,beacon.minor);
          }
           [self.locationManager startRangingBeaconsInRegion:region];   
     }

}

When I run the application on the simulator, and there is a beacon of each network in range, the message is displayed on the console approximately every 10 ms.

I suspect that the stop and restart the ranging is breaking the expected callback flow, but when only one region is in the range, callbacks occur every second as expected.

like image 744
Kepa Santos Avatar asked Jan 09 '23 11:01

Kepa Santos


1 Answers

The problem you describe is common. Other than extending background ranging time (which you have already done), there is no magic bullet on iOS.

Two additional techniques may help. Both of these techniques involve getting a new entry event as you pass from one beacon to the next:

  1. Get hardware beacons that allow you to tune down the transmitter power (my company's RadBeacon products allow this) so the transmissions do not overlap. This way you get an exit event then a new enter event as you move from beacon to beacon.

  2. Redesign your identifier schene so the major field is dedicated to identifying up to 20 different regions (based on UUID and major 1-20). You then monitor for all of these regions. Your individual beacons can still use the minor however you want and specifically as the key to trigger messaging. When placing your beacons, you make sure that none with overlapping transmissions share the same major. This will ensure a new background entry event as you move from one to the other.

like image 93
davidgyoung Avatar answered Jan 11 '23 01:01

davidgyoung