0

When my the screen is locked I can get background calls on this method:

-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region;

I'd like to get more precise data on how far away the iBeacon is. So, I need the didRangeBeacons method.

  • Is it possible to call that method from within didDetermineState in the background?
  • Or is there another method to find out if a beacon is CLProximityImmediate while the app is in the background?
Martijn
  • 15,791
  • 4
  • 36
  • 68
Nico Reese
  • 261
  • 6
  • 14

5 Answers5

1

Yes you can, the best way to do this is to start ranging when you register for region monitoring.

[self.locationManager startMonitoringForRegion:region];
[self.locationManager startRangingBeaconsInRegion:region];

Then after you receive the region callback while you are in the background you will get about 5 seconds of ranging.

I would define the following callbacks:

- (void)locationManager:(CLLocationManager *)manager
      didDetermineState:(CLRegionState)state
              forRegion:(CLRegion *)region
{
  // Get the initial state of the beacon regions
}
- (void)locationManager:(CLLocationManager *)manager
         didEnterRegion:(CLRegion *)region
{
  // Get updates for the beacon regions
}
- (void)locationManager:(CLLocationManager *)manager
        didRangeBeacons:(NSArray *)clBeacons
               inRegion:(CLBeaconRegion *)region 
{
  // Get ranges for actual beacons
}

Just remember that you only get a limited time to do the ranging, and once that background time is over you will stop receiving callbacks.

This means that you only have a few seconds to determine you location. So if you want to trigger an event when the person is a certain distance that might be missed because the background process was stopped by iOS

But if you own the iBeacon hardware you can work around this limitation by adjusting the power output that it is broadcasting. We have been successful by dialing down the power so that the enter region event does not occur until you are very close by the beacon. Estimated distances will need to be recalibrated if you do this, but it can get the job done.

csexton
  • 24,061
  • 15
  • 54
  • 57
0

Yes, you can call startRangingBeaconsInRegion on you CLLocationManager from didDetermineState . Just make sure you check the state is CLRegionStateInside. But remember that, you will only get 2-3 seconds of runtime. So your didRangeBeacons will only get a few callback. After that your app will fall asleep again. A sample come might be like this:

- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region {
    if ([region isKindOfClass:[CLBeaconRegion class]]) {
        CLBeaconRegion *beaconRegion = (CLBeaconRegion *)region;
        if (state == CLRegionStateInside) {
            //now start ranging
            [_locationManager startRangingBeaconsInRegion:beaconRegion];
        }
    }
}

To answer your second question, no. This is the only recommended way.

Max
  • 3,371
  • 2
  • 29
  • 30
0

I have tried many things to make it working in the background even if the screen was off (not illuminating). From my observations this allowed me to make ranging working in the background. You can also try to revoke next time for background work when completion handler gets called. Not sure how it is working under iOS 7.1 but at least for 7.0 it gets a quite good results.

Community
  • 1
  • 1
Julian
  • 9,299
  • 5
  • 48
  • 65
0

In my experience, all four of these are required for continuous ranging updates while the app is in the background:

self.locationManager.pausesLocationUpdatesAutomatically = NO;
[self.locationManager startMonitoringForRegion:beaconRegion];
[self.locationManager startRangingBeaconsInRegion:beaconRegion];
[self.locationManager startUpdatingLocation];

Location updates and Uses Bluetooth LE accessories must also be set in Background Capabilities.

This walkthrough builds an app that gets proximity updates (near, far, immediate) when the app is backgrounded.

James Nick Sears
  • 930
  • 9
  • 16
0

My last startup is about iBeacon, here is some experience.

  1. Your app will have only short period to know current ProximityImmediate after user press home key, after that, your app will have chance to be notified after iPhone left the beacon region by following delegate

    (void) locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region

  2. Your app will have about 10 seconds to know current ProximityImmediate when iPhone screen is light on due to push notification or user press home key. You can fork my code to see how to do that.

Lin Li
  • 11
  • 3