Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
454 views
in Technique[技术] by (71.8m points)

core location - 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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...