Is it possible to use beacon ranging in the background?

Follow

Ranging beacons works always when the app is running, either in the foreground or in the background. However, as soon as the user navigates away from the app or locks the screen, iOS will suspend the app. At this point, ranging stops working until the app is woken up again—which can happen for numerous reasons, e.g.:

  • the most obvious—the user opens the app again,
  • you're doing monitoring and an enter/exit event comes, waking the app into the background for a few seconds so that it can handle the event,
  • you're using background app refresh and iOS wakes the app into the background to allow it to fetch fresh content,
  • etc.

In other words, ranging works just fine in the background, but iOS apps simply aren't given the luxury of running in the background for extended periods of time.

Note that this "ranging works in the background" is different from what most people and resources call "monitoring working in the background". When you start monitoring for beacons, it's the iOS itself that performs the duty, not your app. As a result, even if the app gets suspended or terminated, iOS itself still monitors for beacons. If an enter/exit event happens, iOS will then launch your app to handle the event. Because of that, for long-term beacon detection, monitoring is the recommended way.

To be strict, we should be saying that "ranging works when the app is running (doesn't matter whether in the foreground or the background)" and "monitoring works even if the app is not running".

Short-term background ranging

It's perfectly fine and "legal" to perform short-term background ranging, within the regular background execution capabilities of an iOS app. For example:

  • You can use the fact that iOS wakes/launches your app into the background for a few seconds to handle monitoring enter/exit events, and use those few seconds to range for beacons.

  • You can start a background execution task to extend the time your app can spend in the background. The empirical limit as of iOS 9 seems to be 3 minutes, but you should use the backgroundTimeRemaining property to know for sure how much time your app has in the background before iOS force-terminates it. You can use all this time in the background to perform ranging.

    Imagine for example that you enter a venue, and monitoring triggers an enter event. iOS wakes your app into the background to handle the event, but only gives it a few seconds to do that. The app can then start a background task to extend this time, and start ranging to determine whether the user is moving further into the venue (getting closer to the beacon), or just peeked inside it and immediately leaves. Once you establish that, perform an appropriate action and finish the background task, so that iOS puts the app back to sleep and doesn't forcefully terminate it.

Continuous background ranging

If short-term background ranging is not enough, you need to find a way to keep your app running in the background longer by using Background Modes. However, keep in mind that the use of Background Modes is heavily regulated by Apple! They only accept apps using Background Modes when it's justified—e.g., an app using the "audio" background mode needs to be playing music in the background, etc.

The only Background Mode which remotely makes sense in the context of beacons is the "location" background mode. Even then though, there must be clear value for the end user coming from the use of background ranging, value that can't be fulfilled at all with monitoring. You’ll also have to lay this value out in the review process. Users should also be provided with an easy way to opt-out of this kind of service.

If you’re planning to use the "location" background mode to do long-term ranging without a major user benefit (for example just to track user’s movements for your analytics—i.e., you're the beneficiary, not the user), you will most certainly have your app rejected.

Also, keep in mind the power consumption and performance implications of having your app continuously running in the background with ranging enabled (which keeps the radio going). Nobody wants their app uninstalled because users found out it eats up their battery and slows their device down. For the "location" background mode, Apple requires you to add a boilerplate "Continued use of GPS running in the background can dramatically decrease battery life." line to your app description.

I'm aware of the downsides and the risk of rejection from the App Store, how can I do it anyway?

If you're sure you need persistent background ranging for beacons, you'll need to activate the Background Modes capability for your application—specifically, the Location Updates mode.

Note that for startRangingBeaconsInRegion to work in the background you'll also need to start Standard Location Updates via CLLocationManager's startUpdatingLocation (meaning you need both a CLLocationManager and an ESTBeaconManager in your app).

Note: In iOS 9, you also need to set the allowsBackgroundLocationUpdates property of your CLLocationManager to true.

Note: Even with background location updates running, iOS can still suspend the app if it doesn't detect any changes in the location. (Quote from Apple: "Enabling this mode does not prevent the system from suspending the app, but it does tell the system that it should wake up the app whenever there is new location data to deliver.")

Does it work on Android, too?

Unlike iOS, Android doesn't restrict background processing. We still recommend against running ranging in the background for the very same reasons—battery consumption, performance, and privacy. If you're absolutely convinced you need it to provide the best user experience to the user of your app, you can simply start ranging, and it'll continue even if the user leaves the app.

Was this article helpful?
2 out of 2 found this helpful

8 Comment(s)

  • Avatar
    Ciaran Park

    Very useful Wojtek, However I'm in the middle of developing an Android app that requires background ranging (albeit very infrequently) , do you have any guidance on how to achieve this within Android? Would I need to setup a receiver/service to start the beacon ranging?

  • Avatar
    Wojtek Borowicz

    Hi Ciaran,

    Actually, on Android it's pretty straightforward, as there is nothing preventing you from doing that either on the system or app store (Google Play) side. You can just luanch it the same way you launch monitoring in the background. Keep in mind though that it will have much bigger impact on battery life than background monitoring.

    Cheers.

  • Avatar
    Ciaran Park

    Hi Wojtek,

    That's great, I had assumed using a service it would allow me to and understandably the battery is a big consideration when doing this. I would like to write a library to detect different phones and the radio hardware so I can adapt my detection accordingly, basically smoothing out the results across supported devices. Do you know of anyone who has already done this? or what should I be detecting device side to validate against?

    Thanks for your help so far!

  • Avatar
    Wojtek Borowicz

    Sorry for the late reply! This is rather compelx, because of how fragmented Android is. Unfortunately, I don't know about anyone who tried something like this at scale yet.

    Cheers.

  • Avatar
    Winsey Lee

    This is very clear and useful explanation. Is this method just for background ranging? I would like to improve the background monitoring. When I test my app with the estimotes, I still offer get a few minutes of delay if my app is in background mode.

    I am using iOS Estimote SDK. Thanks for your help! Great article.

  • Avatar
    Wojtek Borowicz

    Hi Winsey,

    Have you tried adjusting the advertising interval of a beacon? It might improve responsiveness of enter/exit region events. Keep in mind though that they have a built-in delay on the iOS system level: especially exit can be delayed by ~30 seconds.

    Cheers.

  • Avatar
    Theo Bendixson

    This is an interesting read Wojtek. We happened to have an app get accepted in spite of its ranging in the background. I'm guessing the reviewers either didn't review it thoroughly enough, or they must have thought our use case is acceptable enough for such a thing.

    Do you have any case studies of apps that have either gotten rejected for ranging in the background or have been accepted in spite of ranging in the background? Did Apple list any particular reasons in favor of or against the use of ranging in the background with regards to said apps?

    It's hard to find a clear answer as to what is acceptable and what isn't when it comes to this particular behavior.

  • Avatar
    Wojtek Borowicz

    Hi Theo,

    Thanks for asking! Apple reviewers decide case by case if the use of Ranging in the background provides enough of a improvement for the user experience to be accepted. In majority of cases though they rule against accepting the app. One notable exception is Robin, a smart office app that uses ranging to determine in which room a user is: http://robinpowered.com/

    Also, would to learn more about your app. Feel free to ping me anytime: wojtek[at]estimote[dot]com :)

    Cheers.

Estimote is
hiring!