iOS - CLLocationManager background operation with MKMapView in foreground - ios

The question "Background GPS in iOS. Is this possible?" does not answer this question.
I have a mapping app that uses MKMapView and its built-in location services when the app is active. When the app is in the background, I would still like location updates to be delivered and processed. For that, I'm using CLLocationManager.
I have location updates enabled in the plist file and call startUpdateLocation in the AppDelegate code which also acts as the delegate for CLLocationManager. This is everything mentioned in "Background GPS in iOS. Is this possible?",
When the app is active, everything works okay, getting updates no problem.
But when put in background mode, the little arrow indicating location services are being used comes on, but then disappears after about ten seconds. In this brief time period, the app seems to be able to receive location updates, but when the arrow is gone, no more updates.
Am I doing something wrong? Does MKMapView override what CLLocationManager wants to do?

Make sure "Background App Refresh" is enabled in your settings. You can check this programmatically by using backgroundRefreshStatus of UIApplication.

To receive location updates in the background, do the following:
Make sure to have a started CLLocationManager
Make sure to have the following value in your info.plist:
"Required background modes" = "App registers for location updates"
Avoid doing a lot of complicated things in your locationManager:didUpdateToLocation. In particular, avoid UI operations. Your execution time is limited by iOS, and not all APIs are available.
Everything is well documented, see "Getting Location Events in the Background" in the documentation.

Related

I want func locationManager(manager: CLLocationManager, didUpdateToLocation to be called even after app is killed?

After my app is killed I want to relaunch the app based on the location.speed paramater, I mean to say when the device speed is>5kmph I want my app to get open and one button needs to be clicked programatically?
NOT POSSIBLE.
You can not execute part of code when you process is killed. Its as simple as that.
You can do this in android with background sevice which run even when you app gets killed because background service is different process. But iOS don't allow to create background service.
Set allowsBackgroundLocationUpdates = true
The default value is NO for allowsBackgroundLocationUpdates
If your app uses location in the background (without showing the blue status bar) you have to set allowsBackgroundLocationUpdates to YES in addition to setting the background mode capability in Info.plist. Otherwise location updates are only delivered in foreground. The advantage is that you can now have location managers with background location updates and other location managers with only foreground location updates in the same app. You can also reset the value to NO to change the behavior.

Blue banner '%MyApp% is Using Your Location' for app that uses location services only when active

In my app I'm updating user location every time when app becomes active. I stop CLLocationManager once updated location is received or in applicationWillResignActive:.
In Info.plist there is a NSLocationWhenInUseUsageDescription with appropriate description.
If app is activated and then immediately moved to background, blue banner saying that '%MyApp% is Using Your Location' appears for less then a second. This banner gets hidden as soon applicationWillResignActive: is called.
I've noticed the same problem in Google Maps, but not in Apple Maps.
Is there a way to get rid of this banner completely? Is there anything else I should do to make iOS happy? I do not want it to freak out my users and prevent them from using cool features that require location.
You have probably set location as Background mode in your info.plist. If you remove that, then the blue bar won't appear anymore.
Or, you can use requestAlwaysAuthorization instead of requestWhenInUseAuthorization on CLLocationManager (and provide the related NSLocationAlwaysUsageDescription in the info.plist file), and then it will not appear either.
In my case, my app is using location in the background in some cases, and I would like the blue bar to appear when that is the case. But I do not want it to appear when exiting the app without location in background. As far as I know that is not possible to achieve (I've asked about it here).
EDIT: Note that starting with iOS-9, you can make sure that the blue bar only appears when the user actually wants the app to use the location in the background. See this answer.
If you want to get access to the user's location with CLLocationManager, the app will need to show that banner and the user will need to press "Allow". If they don't do that, your location manager won't be able to detect the user's location.
Apple's Maps is a special case because it's a first party app.

Location manager icon still displayed even when I call stopUpdatingLocation

Even though I called stopUpdatingLocation on my location manager, the location manager icon is still on the top right of my iPhone. Why hasn't it stopped?
There are several reasons why the location arrow on your phone may still be on even after calling stopUpdatingLocation.
For one, another app on your phone may currently be using your location.
Another possibility is that you enabled significant location change monitoring using the startMonitoringSignificantLocationChanges method but forgot to turn this off using the stopMonitoringSignificantLocationChanges method. Apps that are monitoring significant location changes will display a solid arrow in the status bar in the same way apps that are using standard location updates do.
Of course it's also possible that you are for whatever reason incorrectly calling stopUpdatingLocation and you actually are still getting location updates from a location manager. To check if this is happening wait several minutes after calling stopUpdatingLocation and go to Settings>Privacy>Location Services and find your app. If there is a solid purple arrow next to your app then your app is indeed currently using location services and something most likely went wrong when calling stopUpdatingLocation. However if there is a solid gray arrow, this just signifies that your app has recently used location services and it's likely that you did correctly stop getting updates. Another way to check if you correctly turned off location updates is by calling your CLLocationManager's location property and checking its timestamp property to make sure that it is not recent. If the timestamp is greater than the timestamp at which you called stopUpdatingLocation then you know something is wrong.
The icon you see at the top is not locationManager, is the location service of the device. If you deactivate in settings no longer appears.

Location Services still running after app is killed

I am seeing an issue with Location Services still being used by my app even if the app has been killed from the multitasking bar. If I go into Settings > Privacy > Location Services I notice that my app has a purple location icon even while there are NO apps in the background. If I turn off Location Services for my app, the icon in the status bar disappears.
I have ensured in my app that I am stopping location services when they are not needed. I have verified this numerous times in Instruments. GPS turns on when it is supposed to and when the task is finished using location services, the GPS is turned off.
In my applicationWillTerminate: delegate, I even set the lcoationManager to nil, set the delegate to nil and make sure all of that is cleaned up. I still see the icon in the statusbar when I KILL my app.
This particular app also has a bluetooth accessory that can make the app do certain things. So for instance, I press a button on my BLE accessory and it makes the app do something which will trigger a UILocalNotification, so I see a banner. I don't know how to reproduce this particular issue, but I've noticed that even if there are NO apps in the multitask bar and I press the button on my BLE accessory, it will trigger the action in the app and I will see the notification banner.
A few questions:
Has anyone else seen anything like this?
How can I ensure that my app is COMPLETELY killed even though I have cleaned up really good on application terminated?
Why would the location services still be running even though the app is killed. Also keeping in mind that I do NOT use any region monitoring or significant location update changes.
Update:
So I took a previous version of the app and reset Location & Privacy settings and to my surprise, backgrounding the app makes the location icon disappear (as it should have been doing all along. To me this means that iOS is keeping some residual information or settings from the app? Anyone have any insight as to what could be going on here?
Update 2:
Still occurs in iOS 8.1.x.

CLLocationManager don't stop

Dear fellow developers,
I am trying hard to find a solution for my problem regarfing CLLocationManager.
I use a CLLocationManager instance in my Application. If the user selects the Home button on the device or terminates the application I want the location services to stop.
Therefor I call [self.locationManager stopUpdatingLocation]; - But this somehow doesn't work. The application enters the background and the small location arrow in the upper right corner of the status bar don't disappear. Even if I add [self.locationManager release] or self.locationManager.delegate = nil; - the location tracking don't stop :-/
It only disappears if I go to my device settings and switch off location services for the app. Whenever I switch back to location service enabled I immediately get a purple colored arrow next to the switch toggle and the icon reappears in the status bar.
My question is how can I turn off location services when the app enters the background or is terminated?
Thanks a lot in advance and have a nice day :-)
Your location is disabled. The location service icon "meaning" has changed on iOS 5. Take a look at this question: https://apple.stackexchange.com/questions/27463/why-is-the-location-services-icon-always-present
I Quote the answer:
It's a new feature in ios 5 called "region Monitoring"
The reason it's active even if the app is closed is that this feature
runs in iOS 5 core and notifies all apps that are registered when they
have entered or left a specific geo-fence.
Reminders does that when you use a location based reminder.
Although the location icon appears at all time. This actually has very
minimal impact on the battery due to apple really optimizing this
feature by using cell and wifi mostly.
Your app is working ok. The system behaviour is the one who changed.
You do it the right way. When entering background, it's ok if some delegate methods are called for some seconds. That should stop.
Where do you stop the location updates ? Are you sure it is triggered ? If yes, are your delegate method called even if the visual indicators tell something else ?
Are you sure you don't trigger a method that reactivate the location update after you have stopped it (because for example you can receive some updates even after stopped).
For instance if you started monitoring a significant location change, then you should unsubscribe from it with the corresponding pair method. If you are using region enter, then until you unsubscribe, the system will notify your delegates.

Resources