I'm wondering if, in iOS8 with all possible background-modes turned on, the app will be woken up after termination to deliver location updates using the standard-location updates monitoring?
I've read all possible documentations, but I find it quite confusing because it at one point says the device will wake up the app, and at another point is says the device will not wake up the app when using standard-location updates.
My app needs continuous location updates with a movement-threshold of about 150 meters (max), and therefore the standard-location-monitoring seems appropriate. It also needs to keep getting these updates even if the app is terminated by the system, as it is crucial to the user.
I've come to understand that if using the significant change location monitoring the app will be woken up upon delivery of new data, but I'm still confused about the standard location monitoring when having requested Always authorization and having the background updates for location turned on.
Have anyone tested this, or know what happens? And if the app is not woken up after being terminated by the system, how can I solve that problem?
Thanks.
Standard location is something your app does. Thus your app needs to be running. It can operate in the foreground or you can even run in the background. But if your app is not running, it's not running; there is nothing to track.
Significant location monitoring and region monitoring, on the other hand, are done for you by the system, so it runs even if your app is not running, and you are woken up or launched to receive updates.
Related
I have an app which supports background monitoring. For my app to be able to register background movement of device I must call startMonitoringSignificantLocationChanges(). However, at some point in my code I must also call startUpdatingLocation().
My question is, if I call startMonitoringSignificantLocationChanges() and later in my code I call startUpdatingLocation(), will significant monitoring be overridden? Specifically, if I terminate my app will my location manager still receive updates on significant location changes?
After a few testings I’ve come to a conclusion that even if “live” location updates are activated, significant location changes notifications will still be received while running app in background or when terminated. Hope others will find this useful.
Is it possible to update location when application is in suspended/terminate state.
i want to update location every 500 meters when app is in suspended/terminate state.
thanks in advance.
When terminated the only real way to get updates is to use Region Monitoring but you will only get major updates so I doubt it will work for 500 meters.
From the documentation:
If your app is terminated either by a user or by the system, the
system doesn't automatically restart your app when new location
updates arrive. A user must explicitly relaunch your app before the
delivery of location updates resumes. The only way to have your app
relaunched automatically is to use region monitoring or
significant-change location service. However, when a user disables the
Background App Refresh setting either globally or specifically for
your app, the system doesn't relaunch your app for any location
events, including significant change or region monitoring events.
Further, while Background App Refresh is off your app won't receive
significant change or region monitoring events even when it's in the
foreground.
There are good reasons for this. Firstly people don't want apps that 'snoop' on them all the time and even if there is a good reason imagine having 10 apps doing this constantly. It's going to start causing you performance and battery life issues.
EDIT
There appears to be some confusion by a lot of people over this issue so I will attempt to clear things up a bit.
Your app is NOT supposed to be continually tracking location while terminated (or suspended really). You are just not allowed to do this both for privacy reasons and so that you don't drain the battery excessively.
While your app is in the foreground you can use location services via startUpdatingLocation to monitor the device location. Assuming the app has been granted permission this will use all available hardware (GPS, WiFi, Cellular).
Now from the documentation itself:
If you start this service and your app is suspended, the system stops
the delivery of events until your app starts running again (either in
the foreground or background). If your app is terminated, the delivery
of new location events stops altogether. Therefore, if your app needs
to receive location events while in the background, it must include
the UIBackgroundModes key (with the location value) in its Info.plist
file.
So once suspended and terminated your options are really to monitor regions and to monitor for significant location changes. Neither of these are particularly accurate or frequent. One reason for this is that they only use low power methods to get the position (WiFi and Cellular) they don't use the GPS.
So no accurate and/or frequent location tracking while an app is suspended or terminated. This just has to be accepted and you need to design your apps accordingly.
let locationManager = CLLocationManager()
locationManager.startMonitoringSignificantLocationChanges()
After returning a current location fix, the receiver generates update events only when a significant change in the user’s location is detected. It does not rely on the value in the distanceFilter property to generate events
If you start this service and your app is subsequently terminated, the system automatically relaunches the app into the background if a new event arrives. In such a case, the options dictionary passed to the application(:willFinishLaunchingWithOptions:) and application(:didFinishLaunchingWithOptions:) methods of your app delegate contains the key location to indicate that your app was launched because of a location event. Upon relaunch, you must still configure a location manager object and call this method to continue receiving location events. When you restart location services, the current event is delivered to your delegate immediately. In addition, the location property of your location manager object is populated with the most recent location object even before you start location services.
Apps can expect a notification as soon as the device moves 500 meters or more from its previous notification. It should not expect notifications more frequently than once every five minutes. If the device is able to retrieve data from the network, the location manager is much more likely to deliver notifications in a timely manner.
Hope It helps
I apologise for the redundancy of this topic, but in spite all the given answers, I can't identify the possibility of getting accuracyBest location updates when the app is terminated.
I don't want to use monitoringSignificantChange, I want the best possible accuracy; I won't submit the app on the AppStore, so Apple restrictions are not a problem either.
I have gone through these:
-Location update even when app is killed/terminated
-iOS update location even when app is terminated
-Working with location updates when app is terminated
-http://mobileoop.com/getting-location-updates-for-ios-7-and-8-when-the-app-is-killedterminatedsuspended
and many more, but it is not clear whereas it's possible or not. I currently have my project, everything works great with significantChange but I now need better accuracy.
Could somebody tell me straight forward if getting best accuracy location update when app is killed is possible please ?
Thank you infinitely,
Looking at the below content from the Apple doc, you clearly have 2 alternatives against using significant location changes to wake a app from the background. I have marked in bold the services you can use to relaunch the app if it has been terminated.
Using Location Services in the Background Most location services are
meant to be used while your app is in the foreground but some can also
run in the background. In some cases, location events can even cause
your app to be relaunched to process an event. To run most location
services in the background, you need to enable the location updates
background mode in the Capabilities tab of your Xcode project. For
services that launch your app, you need to request (and be granted)
“Always” authorization from the user.
The standard location service delivers events normally while an app is
running in the foreground. When your app is in the background, this
service delivers events only when the location-updates background mode
is enabled for the app. This service does not relaunch iOS apps that
have been terminated.
The significant location change service delivers events normally
while an app is running in the foreground or background. For a
terminated iOS app, this service relaunches the app to deliver
events. Use of this service requires “Always” authorization from the
user.
The region monitoring service delivers events normally while an
app is running in the foreground or background. (You can use this
service for both geographic and beacon regions.) For a terminated
iOS app, this service relaunches the app to deliver events. Use of
this service requires “Always” authorization from the user.
Beacon ranging delivers events normally while an app is running in the
foreground. When your app is in the background, this service delivers
events only when the location-updates background mode is enabled for
the app and the standard location service is running. (If the beacon
region’s notifyEntryStateOnDisplay property is YES, waking the device
causes the app to range for beacons for a few seconds in the
background.) This service does not relaunch iOS apps that have been
terminated; however, you can be relaunched by monitoring beacon
regions using the region monitoring service.
The heading service delivers events normally while an iOS app is
running in the foreground. When your app is in the background, this
service delivers events only when the location-updates background mode
is enabled for the app and the standard location service is running.
This service does not relaunch iOS apps that have been terminated.
The visit service delivers events normally while an iOS app is
running in the foreground. When your app is in the background, this
service delivers events only when the location-updates background mode
is enabled for the app and the standard location service is running.
For a terminated iOS app, this service relaunches the app to deliver events. Use of this service requires “Always” authorization from the
user.
Enabling the location-updates background mode ensures that an app
continues to receive location events while in the background. When the
app moves to the background, the system adds the location-services
indicator to the status bar to let the user know that an app is using
location services. The system may still terminate the app at any time
to reclaim its memory or other resources.
Also from the doc,
Getting the Visited Locations
In iOS, the visits service provides an alternative to the significant location change service for apps that need location
information about interesting places that the user visited. For
example, if the user is in one location for an extended period of
time, the service might generate an event when the user arrives at
that location and another when the user leaves that location. The
service is intended for apps that might already be using the
significant location change service and want an even lower power way
to do so. You would not use this service to create navigation apps or
apps that rely on regular location updates.
Document Link:
https://developer.apple.com/library/ios/documentation/CoreLocation/Reference/CLLocationManager_Class/index.html#//apple_ref/doc/uid/TP40007125-CH3-SW73
Continuous location updates stop when your app is terminated.
Geo-fence notices will re-launch your app even if it's not running. I think a significant location change will also relaunch you're app but I'm not as sure about that.
Once you're relaunched you can start location updates again with the accuracy set to best like you want, but I think you're going to need to use one of those two APIs to get relaunched again after you've been terminated.
I am creating an application that sends updated location to server regardless of app state. I have tried silent push to wake my application in background but it didnt work (it works fine except if my app is killed by user from app switcher). I am using location manager for getting current location.
Does IOS7 provides this feature to launch your application in background (even if app is killed by user from app switcher)??
I have spent five days without any success on this. If anyone can help me that would be highly appreciable.
Thanks in advance!!
If you need precise GPS locations you can set add the "location" value to the UIBackgroundModes array in your Info.plist as described in "UIBackgroundModes location and significant location changes with region monitoring". If you need only approximate locations you can use the startMonitoringSignificantLocationChanges method of CLLocationManager. As it is written in the documentation: "If you start this service and your application is subsequently terminated, the system automatically relaunches the application into the background if a new event arrives."
You can wake your app by using significantlocationchange.
You have to start significant location change while you switch your app to background.
Then system will wake your app after significant location change.
The frequency is not faster than 5 min and for every 500 meters.
You will have to catch the event by checking for LocationKey in didFinishLaunchingWithOptions in projects AppDelegate.
We are working in a groupon-like app where alerts are displayed to the user when he/she enters in the range of an offer.
The client insists on having alerts even when the app is in the background.
Due to the architecture of the system, the app gets the location of the client at intervals and checks with the server if there is any new alert. If so, the app does some processing in the local database and displays a notification.
APN cannot be used since changes in the server are out of reach for this project.
My question is whether Apple would accept it in AppleStore as I have read different opinions about it and Apple discourages its use as in this extract from iOS Developer Library
http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html
At wake-up time, your app is put into the background and given a small amount of time to process the location data. Because your app is in the background, it should do minimal work and avoid any tasks (such as querying the network) that might prevent it from returning before the allocated time expires. If it does not, your app may be terminated
Thanks
How often does your app get location from the user? According to Apple's Background Execution and Multitasking, if you are getting the location updates on a regular schedule (I think it's less than 10 minutes), your app can still process in the background if you add location to UIBackgroundModes in your info.plist. With those CLLocation coordinates, you can then process your web service requests.
I personally have not done something like this, so I can't tell you for sure if Apple will reject your app or not. However, if everything is within the guideline and requirements set by Apple, I don't see why they would reject your app.
EDIT:
From the Apple doc:
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.
I guess even if the app is suspended, it will wake up whenever there is a new location data to deliver.
I think you should reconsider your approach for this application. It sounds like you have decided to build a set of features which are not necessarily well informed by, or a good fit for, the characteristics of the devices the app will run on.
You write that "the app gets the location every n minutes" but that's not how iOS location services work. Querying location services for the current location occasionally is a good approach when your app is running in the foreground but that's not an option once it is suspended or terminated. Instead you need to subscribe to location events, at some level of accuracy, and your app will be notified when the device's location changes. There are no guarantees about the schedule on which you receive these events and it varies depending on the accuracy you request and the speed at which the device is moving.
Additionally, obtaining a location is an expensive operation and can quickly drain the device's battery. Burning through a user's available battery power in an hour or two is a very good way to get your app uninstalled quickly. Where possible you should be using the significant location change service to get low accuracy location updates with minimal power consumption. If you need more precision then consider using boundary crossing events for a defined region or at least reduce the accuracy your have requested as much as possible.
With all that out of the way you still need to work within the limited time your app has to run once started by a location update. That's probably not long enough to make a round trip to the server. If a network connection is already active and the device happens to have low latency you will probably get a response some of the time but I would expect to see the app terminated by the OS frequently. When that happens I don't know that you will continue to receive location updates which might otherwise re-launch the app.
Instead of downloading a list of alerts and displaying them locally a better solution might be to attempt to send your current location to the server via UDP when you see a significant location change. That way you can fire off a network request without waiting for a response. Only some of those requests will still succeed but at least your app won't be terminated. You can then process the locations you receive on the server and send push notifications when appropriate.
I realize that you don't seem to be able to make server side changes. In that case the best you might be able to do is pre-fetch alerts for the nearby region when the app runs (and if you ever manage to complete a round-trip while in the background). That way you could compare location updates to that list and not need to fire off a network request on every location update. Unfortunately it sounds like you might be backed into a corner here with no reliable solution available under your current constraints.