I am trying to work out how to start updating locations when triggered by a CLRegion in iOS 8 & 9. The use case is that a user gets to a certain predefined starting point (determined by region monitoring) for a regular journey and then the app tracks that journey till it is ended, without need for user interaction. In my testing so far, if I call startUpdatingLocation from within didEnterRegion the updates stop within 10 seconds which I presume is the standard background window for processing a location event. I need those updates to continue until they are explicitly turned off. I have also experimented with switching on SLC followed by standard location but also with no luck. I do however occasionally get some further updates (10 seconds worth) if I touch the home or lock buttons, but this is unreliable. All the examples I have found so far assume that location events are started from the foreground and continued in the background, but in this case I need to have updates started while the app is in background, and to continue in a reliable manner.
Let me give an explanation of what is going on.
Everything below assumes two things:
- You have asked and obtained "always" authorization
- You have the 'location' UIBackgroundMode (with all the issues it will bring when crossing the bridge at App Review time Please read app guidelines regarding background modes before committing to use the location background mode)
When you have the above two items sorted out, your app can make the startUpdatingLocation call anytime, foreground or background.
The location updates will start in either case. What changes is, when the startUpdatingLocation call is made while the app is in the foreground (and the 'location' UIBackgroundMode is set), the system holds a background task assertion for your app; meaning your app will not be suspended as long as the location updates are running.
In the case of calling startUpdatingLocation while your app is in the background, CoreLocation still responds by starting the location updates for your app, but the system will no longer hold an assertion for you, and your app will be suspended once the allowed time in the background is spent. The documentation is technically correct - you can start location updates from either state - staying active withuot being suspended is another story.
This time is (currently) is 10 seconds, which is why you think updates stop after 10 seconds. But actually your app is now suspended and can no longer receive the updates. There is a way to extend this duration to (currently) up to 3 minutes by employing beginBackgroundTaskWithExpirationHandler: (Read more about it here: https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html#//apple_ref/doc/uid/TP40007072-CH4-SW1
Whether this extended time is enough will depend on your app.
If your goal in trying to wait until later to start location updates is power saving, there are other ways as well.
- if it is suitable for your use case, Significant Location Change service is quite efficient, and a better match to use in conjunction with the standard location service
- you can start location updates when your app is in the foreground and defer location updates while your app is in the background. As your app tracks journeys which would have a start and an end, having location updates running during the journey, while deferring the updates could be suitable for your case.
When the updates are deferred, the system will wake your app when it decides it is power efficient to do so. You can read more about that here: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html#//apple_ref/doc/uid/TP40009497-CH2-SW14
Also, I suggest you watch the WWDC 2015 presentation "What's new in Core Location" to find out what is coming in iOS 9. There is a new way to get the current location easily which might be of interest to you, and there is an additional step to get background location updates to work. The video is here: https://developer.apple.com/videos/wwdc/2015/?id=714
I am not able to determine from your question whether you are using (or planning to use) the location UIBackgroundMode. The above is assuming you do. If you don't, there will be no standard location updates for your app past the limited time you have in the background. Again, make sure your app is suitable for the use of this mode according to the guidelines to avoid issues at App Review time.