How is it possible to keep CLLocation updating in the background. I believe you need to register the application to do this in the Application delegate but I can not find a reference to this anywhere?
Here is a link to the relevant documentation:
https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html#//apple_ref/doc/uid/TP40007072-CH4-SW20
in particular, see this paragraph:
An application can declare itself as needing continuous background location updates. An application that needs regular location updates, both in the foreground and background, should add the UIBackgroundModes key to its Info.plist file and set the value of this key to an array containing the location string. This option is intended for applications that provide specific services, such as navigation services, that involve keeping the user informed of his or her location at all times. The presence of the key in the application’s Info.plist file tells the system that it should allow the application to run as needed in the background
Related
This question already has answers here:
Periodic iOS background location updates
(9 answers)
Closed 5 years ago.
I have an app that is used for tracking van drivers. I need to be able to get the location (x&y) every 30 seconds or so. I have a method and a timer that allows me to do this.
I was wondering how (if at all possible) I can have this working regardless of whether the app is active or not?
I've recently started messing around with core-location so my knowledge my not be bullet-proof.
If the app is is still active but only in the background then as long as you set the allowsBackgroundLocationUpdates to true then you will get updates. But this could become battery consuming, it could go on until your battery dies.
You may want to avoid constant location checking by setting:
pausesLocationUpdatesAutomatically to true.
However if you do set it to true then if your driver stops at a location for too long(I don't know what means too long) then the app would stop completely from tracking location until you bring the app to foreground again. I'm saying that based on:
Important For apps that have in-use authorization, a pause to location
updates while in the background ends access to location updates until
the app returns to the foreground and is able to restart location
services. If you do not wish location updates to stop entirely,
consider disabling this property and changing location accuracy to
kCLLocationAccuracyThreeKilometers when your app moves to the
background. Doing so allows you to continue receiving location updates
in a power-friendly manner.
So it's a little tricky. You may want to set pausesLocationUpdatesAutomatically to true but then if your business requirements allow...do something like stopUpdatingLocation() after 1hr of app being in background to stop location updates completely.
Yes, this is possible.
If your iOS app must keep monitoring location even while it’s in the background, use the standard location service and specify the location value of the UIBackgroundModes key to continue running in the background and receiving location updates. (In this situation, you should also make sure the location manager’s pausesLocationUpdatesAutomatically property is set to YES to help conserve power.) Examples of apps that might need this type of location updating are fitness or turn-by-turn navigation apps.
For more information, check out the Location and Maps Programming Guide.
So my question is whether an app, which is running in the background, can access the device's location information and save it in the heap or send data to a server?
I know it would have to do something with the delegate but I'm not sure a process of this complexity can be done while the app is in the background
Yes, you can!
In the Location Awareness Guide of apple its is described that application that need to receive GPS in the background have to set a specif value:
Set key location in the UIBackgroundModes array of your Info.plist file.
Yes. You can do it.
By setting the proper key-value in info.plist file, your application will able to fetch locations even when its in background.
Using ASIHttpRequest (Link), you can upload the data using web service.
For that, create the object of ASIHTTPRequest and keep the value of shouldContinueWhenAppEntersBackground to TRUE.
I have an app that uses a combination of startMonitoringForRegion: and startMonitoringSignificantLocationChanges to keep aware of where the user is when the app is in the background. Does this mean that I need to include the location value for the UIBackgroundModes key in the Info.plist?
This is a quote from the docs:
The significant-change location service is highly recommended for apps that do not need high-precision location data. With this service, location updates are generated only when the user’s location changes significantly; thus, it is ideal for social apps or apps that provide the user with noncritical, location-relevant information. If the app is suspended when an update occurs, the system wakes it up in the background to handle the update. If the app starts this service and is then terminated, the system relaunches the app automatically when a new location becomes available. This service is available in iOS 4 and later, and it is available only on devices that contain a cellular radio.
...
An app that provides continuous location updates to the user (even when in the background) can enable background location services by including the UIBackgroundModes key (with the location value) in its Info.plist file. The inclusion of this value in the UIBackgroundModes key does not preclude 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. Thus, this key effectively lets the app run in the background to process location updates whenever they occur.
My interpretation of this is that the location value for the UIBackgroundModes key is only required if the app needs continuous location updates, like a sat nav app.
I have also tried running the app on a device without the location value for the UIBackgroundModes key and it continues to report significant location changes and when the a region is entered of exited.
Also, the only place that UIBackgroundModes is mentioned in the CLLocationManager Class Reference is in the startUpdatingLocation discussion, which I am not using.
You're right about the location key, it's only required when your app needs high-precision location updates even when in the background. Something like Runkeeper uses this to allow it to keep tracking your location, even when you're using another app with multitasking. From the docs for iOS Keys: UIBackgroundModes
"location": The app provides location-based information to the user and requires
the use of the standard location services (as opposed to the
significant change location service) to implement this feature.
And
Where alternatives for running in the background exist, those alternatives should be used instead. For example, apps can use the signifiant location change interface to receive location events instead of registering as a background location app.
Region monitoring will work without the location key. In fact, region monitoring will work without any special iOS keys being enabled.
You say that you're not using CLLocationManager, but if you're using region monitoring, you'll have to use that class. You need to set up a location manager delegate for your app to actually get the region notifications.
Yes, you must need to add "location" key under Backround modes in Info.plist if you are using significant change location service (startMonitoringSignificantLocationChanges) to monitor user location in the background and in the app kill state.
My question is: Is CLLocationManager continue running, while my app is inactive?
Yes, if CLLocationManager is first called startUpdatingLocation method, and in the AppName-Info.plist file is added Required Background Modes -> App registers for location updates
Yes, it could. You have two options for handling location service events when your app is suspended, which can be read at the article: Getting the User’s Current Location.
As noted:
There are two different services you can use to get the user’s current location:
The standard location service is a configurable, general-purpose solution and is supported in all versions of iOS.
The significant-change location service offers a low-power location service for devices with cellular radios. This service is available only in iOS 4.0 and later and can also wake up an application that is suspended or not running.
Also, as noted at the bottom of this article in the section "Getting Location Events in the Background":
If your application needs location updates delivered whether the application is in the foreground or background, there are multiple options for doing so. The preferred option is to use the significant location change service to wake your application at appropriate times to handle new events. However, if your application needs to use the standard location service, you can declare your application as needing background location services.
An application should request background location services only if the absence of those services would impair its ability to operate. In addition, any application that requests background location services should use those services to provide a tangible benefit to the user. For example, a turn-by-turn navigation application would be a likely candidate for background location services because of its need to track the user’s position and report when it is time to make the next turn.
There are some important subtleties with this (as of iOS 7.1):
The Location Update background mode should NOT be used if you are just looking for significant change and region enter/exit events. You will still receive these events even if the background flag is NOT set, and you will save a lot of battery at the same time.
If you do the above, you need to be mindful of limited permitted background time. If you don't take care to wrap up network requests etc. in the permitted time, you will network transaction failures.
You should ONLY use the location background mode if you need to use detailed location tracking (e.g. -startUpdatingLocation), in which case this background mode will keep your app awake.
Using the location background mode when not getting detailed location will piss off your users and may get your app rejected during the review process (depending on how you use location throughout your app).
Your app may be killed at anytime by the OS if you do not have the background location mode set, so you will need to be sure to properly re-initialize your CLLocationManager instance in applicationDidFinishLaunching or applicationWillFinishLaunching in order to get the subsequent updateLocation or didEnter/ExitRegion delegate call. Just because location wakes up your app with a location update, it does NOT magically re-create your CLLocationManager without you programming it!
Hope that helps!
To disable CLLocationManager while the app is in backround mode you simply must not add the
"App registers for location updates"
in the
"Required background modes"
key of the info.plist file.
I suggest to use the significant-change location service instead of the standard location service whenever possible, to preserve device battery.
I can get the current location of my iPhone but I was wondering if it is possible to call my methods when application is in background and pop-up message(may be using local notification?) if user has reached at particular location.
Thanks.
Yes, this is possible. A local notification is also an excellent solution.
All you need to do is to set the flags for background position updates in the app plist. Then, in the callback methods for the location manager, perform the distance and/or location tracking logging and fire a local notification.