Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Beacon Ranging in Background on iOS

I understand the difference between monitoring and ranging, and I understand the limitation of iOS in that beacon ranging can only happen in the foreground or in the background when entering and exiting regions as explained here (http://developer.radiusnetworks.com/2013/11/13/ibeacon-monitoring-in-the-background-and-foreground.html). But I'm trying to figure out how to solve a common scenario.

If I had a bunch of beacons installed in a department store, how am I supposed to detect when a person moves within range of those beacons? With the way it currently works, the app will get an event when the user enters the store (didEnterRegion) because the collection of all beacons acts as one big region. But there's no way to know that a user is moving between different sections of the store unless the beacons are placed far enough for the user to exit and enter the region again which is probably not practical.

The reason I want to range for beacons in the background is that I might need to know that a user is at a specific section/product in the store to display specific offers/information (through a notification) for that section without needing the user to have the app open.

This seems to me like a very common scenario for malls and museums, etc... I'm wondering how other developers solved this or whether there's another way of achieving what I want.

I didn't include code snippets here because the issue is not with the code, it's just a conceptual issue. If any clarification or code is needed I can add that too.

Thanks

like image 943
Moe Salih Avatar asked Oct 14 '14 19:10

Moe Salih


People also ask

How do I use my Iphone as a beacon?

To use an iOS device as an iBeacon, you do the following: Obtain or generate a 128-bit UUID for your device. Create a CLBeaconRegion object containing the UUID value along with appropriate major and minor values for your beacon. Advertise the beacon information using the Core Bluetooth framework.

Can I use a beacon without an app?

Beacons are not an end solution that can be purchased and deployed without any code. They need to be connected to a mobile app which means either building your own iOS/Android app or using one of the available third-party platforms.

What is beacons in iOS?

An iBeacon is nothing more than a Bluetooth Low Energy device that advertises information in a specific structure. Those specifics are beyond the scope of this tutorial, but the important thing to understand is that iOS can monitor for iBeacons that emit three values known as: UUID, major and minor.

What is beacon in mobile?

What is a beacon? A beacon is a small device (approx 3cm x 5cm x 2cm) that constantly sends out radio signals to nearby smartphones and tablets, containing a small amount of data. The signal strength and time between each signal can be configured to give a desired coverage.


1 Answers

The biggest part of the answer is the technique documented by my colleague @csexton in another answer to this question.

In order to solve the second problem of only getting 10 seconds of ranging time after a transition, you can request additional time to keep ranging. iOS allows you to continue ranging in the background for up to 180 seconds. This requires no background modes and no special permission from the AppStore.

Here's how you set that up:

- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
    if (_inBackground) {
        [self extendBackgroundRunningTime];
    }
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [self logString: [NSString stringWithFormat:@"applicationDidEnterBackground"]];
    [self extendBackgroundRunningTime];
    _inBackground = YES;
}


- (void)extendBackgroundRunningTime {
    if (_backgroundTask != UIBackgroundTaskInvalid) {
        // if we are in here, that means the background task is already running.
        // don't restart it.
        return;
    }
    NSLog(@"Attempting to extend background running time");

    __block Boolean self_terminate = YES;

    _backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithName:@"DummyTask" expirationHandler:^{
        NSLog(@"Background task expired by iOS");
        if (self_terminate) {
            [[UIApplication sharedApplication] endBackgroundTask:_backgroundTask];
            _backgroundTask = UIBackgroundTaskInvalid;
        }
    }];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"Background task started");

        while (true) {
            NSLog(@"background time remaining: %8.2f", [UIApplication sharedApplication].backgroundTimeRemaining);
            [NSThread sleepForTimeInterval:1];
        }

    });
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    [self logString: [NSString stringWithFormat:@"applicationDidBecomeActive"]];
    _inBackground = NO;
}

Getting 180 seconds to range in the background is no silver bullet, but it solves many use cases that 10 seconds does not.

You can read a full writeup on how this works, along with test results here: https://github.com/RadiusNetworks/ibeacon-background-demo/tree/background-task

like image 105
davidgyoung Avatar answered Sep 21 '22 19:09

davidgyoung