1

I want to do the following:

If a user remains still in a CLBeaconRegion for an extended period of time (roughly 15 minutes), I want to be able to execute some piece of code. This problem is trivial if the app is in the foreground, but I'm having trouble extending the background time to the allotted time. Because I am using location services, it should be permissible to have such a long background task running.

Both didEnterRegionand didExitRegion are called in the background only when the user moves. There does not appear to be any location-specific API that allows you to do background tasks in respect to time.

There does appear to other similar questions that want to achieve the same thing, such as all the threads mentioned here. However, it doesn't seem that the proposed solutions would work for a CLBeaconManager (which essentially involves disabling and enabling CLLocationManager when the backgroundTimeRemaining is sufficiently small, but my initial attempts with this solution didn't work out)

Another way I can do this with a limited scope is to schedule a notification in 15 minutes, and cancel the notification in didExitRegion.

However, the solutions above feel either hacky or inadequate. Is there an "elegant" way to accomplish what I want?

Community
  • 1
  • 1

1 Answers1

0

So long as you have location background mode requested in your Info.plist, your backgroundTimeRemaining should return a very large value, essentially indicating infinite background running time. This should allow you to put a block of code like this in your didEnterRegion method and have it go off.

let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(15*60 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) {
    print("It's been 15 minutes since we entered the beacon region.")
}

I noticed that you get infinite background running time by putting location background mode in your Info.plist when researching the technique of running a background thread to extend beacon ranging in the background. You can look at the code in the link to see how I started my background thread.

davidgyoung
  • 63,876
  • 14
  • 121
  • 204
  • I have location background mode enabled in Info.plist. Checking for `backgroundTimeRemaining` in `didEnterRegion` does say it is infinite. However, checking for `backgroundTimeRemaining` some time later indicates that it still counts down from 180 seconds. – Elvis Parsley Jul 28 '16 at 14:48
  • Interesting. I wonder if the difference is that I had ranging turned on? if that works, perhaps you could do ranging for 15 minutes, and stop it when the 15 minutes is over. – davidgyoung Jul 28 '16 at 16:11
  • Unfortunately I wasn't able to replicate your results. (I don't think I would want to leave ranging on for 15 minutes anyways) Ranging gave infinite `backgroundTimeRemaining` for about 5 seconds, and then it started counting down again. Are you saying that just enabling location background mode will give unlimited background time? That seems contrary to a lot of the literature about background modes. – Elvis Parsley Jul 28 '16 at 18:46
  • Are you sure you have the "UIBackgroundModes" key with an array entry of "location"? – davidgyoung Jul 28 '16 at 18:56