I want to get location updates of user even after the app is terminated from background mode or if its in the background mode. It has to work for both the cases.please provide any demo link for the same.
You can't get the location update in terminated mode.
Please see : - Getting User Current Location
For getting location in background please use the following code to authorization
locationManager = CLLocationManager()
locationManager?.delegate = self
locationManager?.requestAlwaysAuthorization()
Authorization alert will be appear like this.
Select Always allow for getting location in background mode.
Related
I am currently testing the background location mode in iOS 13, as I want to track the user´s location and motion (using the CMMotionManager) in the background.
Therefore, I have my own (singleton) class handling the location tracking. I initialize the CLLocationManager in the following way:
func initializeLocationManager() -> CLLocationManager {
let manager = locationManager ?? CLLocationManager()
manager.delegate = self
manager.requestAlwaysAuthorization()
manager.allowsBackgroundLocationUpdates = true
manager.pausesLocationUpdatesAutomatically = false
manager.distanceFilter = kCLDistanceFilterNone
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.activityType = .other
return manager
}
Then I start the following services:
func startLocationServices() {
// ...
locationManager.startUpdatingLocation()
locationManager.startMonitoringVisits()
locationManager.startMonitoringSignificantLocationChanges()
// ...
}
In addition, I implemented the CLLocationManagerDelegate-methods didChangeAuthorization(), didUpdateLocation().
In the info.plist-file I appended the following entries:
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>...</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>...</string>
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
In my ViewController, I call the startLocationServices.
Currently, I set the app's authorization to track location data to ".authorizedAlways"
The location updates stop after approximately 60 - 130 minutes.
To solve the problem, I already added the didFinishLaunchingWithOptions-function, which triggers the location-updates again:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if let launchOptions = launchOptions,
let isLocationKey = launchOptions[UIApplication.LaunchOptionsKey.location] as? Bool,
isLocationKey {
restartServices()
}
return true
}
When the app gets awoken using this function, I managed to get continuous data on some tests, but sometimes the app was suspended again after a few minutes.
Last, I also tried a timer that restarts the location tracking every 5 minutes, but this does not seem to affect the update-duration at all.
So my question is if there is a way of continuously receiving the location updates in the background, or is there some option I am missing?
Thanks in advance.
Edit: I tested the application on iOS 12 and it gets continuous updates in 5/5 tests.
So I guess the problem is related to iOS 13.
Nothing is wrong with code !! ,
I have faced the same issue and after research I found that
At the WWDC19 keynote Apple announced two changes in the way location permissions will work in iOS 13. The first change gives users the option to share their location with your app just once. This makes it easier to try out location features and helps users keep sensitive location data private.
The first notable change is that even when you call requestAlwaysAuthorization, the user will only get the ‘just now’ and ‘when in use’ options in the permission dialog. If the user grants you ‘when in use’ permission and you try to scan for location in the background, only then the user will be presented a dialog to grant the background permission.
So When user grants WhenInUseUsage permission You will get always in CLAuthorizationStatus and If user choose Allow Once CLAuthorizationStatus will be rested to notDetermined once app launches again
You can check this article for detailed info
https://medium.com/q42-engineering/apple-location-permission-ios13-1e0e59002889
And Here is video https://developer.apple.com/videos/play/wwdc2019/705/
EDIT
After When In User permission granted by the user iOS will show user a another dialogue after some days to change permission from when in use to always allow.
So now there is no way to directly ask user for always allow permission instantly like we do before.
This is an iOS 13 bug. The app permissions get messed up by iOS. While it shows "Always" in settings, it actually behaves more like "While in Use". One app is put to sleep in background while other keeps getting locations on the same device (in background).
To solve it, goto Settings-> Search your app with issue -> Location -> Change Always to Never and then back to Always.
Unfortunately, there is nothing, you can do in the code to fix this.
I used loc_manager.startMonitoringSignificantLocationChanges() but didUpdateLocations not calling in foreground ,background and suspend mode can anyone help me please,
override func viewDidLoad() {
super.viewDidLoad()
loc_manager.requestAlwaysAuthorization()
loc_manager.allowsBackgroundLocationUpdates = true
loc_manager.delegate = self
loc_manager.desiredAccuracy = kCLLocationAccuracyBest
loc_manager.pausesLocationUpdatesAutomatically = false
loc_manager.distanceFilter = kCLDistanceFilterNone
}
For Location in foreground
In the foreground the CLLocationManager object and delegates will do fine. This will also work with the 'while in use' location permission.
For Location in background
Please enable the Background Modes from the capabilities of the project and enable the 'Location updates'. After enabling this, the only configuration to get the updates in the background(not in killed state) is to set'allowsBackgroundLocationUpdates' to true(which you have done already).
For more information on getting location in the background follow :
https://developer.apple.com/documentation/corelocation/cllocationmanager/1620568-allowsbackgroundlocationupdates
For location in application suspended or killed
Here the significant location changes are only needed when you want to get the location when the application is killed by the user(or Suspended). This significant location change will launch the application in background and read the location of the device. This mode needs 'Always authorised' location permission.
For significant location changes while the application is in killed state, follow below link. This is in objective C but it can be easily done in swift also.
http://mobileoop.com/getting-location-updates-for-ios-7-and-8-when-the-app-is-killedterminatedsuspended
Hope this helps.
I am writing (in Swift) an iOS 9 app that needs location updates including in background mode. The problem is that I only get location updates in foreground. I think I have done everything correctly:
In info.plist:
Specified a value for NSLocationAlwaysUsageDescription.
Specified a value for NSLocationUsageDescription.
Specified a value for NSLocationWhenInUseUsageDescription.
Included "location" in UIBackgroundModes.
Included "gps" and "location-services" in UIRequiredDeviceCapabilities
Started the location manager as follows:
let locationManager = CLLocationManager()
locationManager.desiredAccuracy =
kCLLocationAccuracyHundredMeters
locationManager.distanceFilter = 250.0
locationManager.allowsBackgroundLocationUpdates = true
locationManager.startUpdatingLocation()
I have also verified that
locationManager.pausesLocationUpdatesAutomatically is false.
I get no location updates while the app is not in the foreground. The only time I do get location updates is if I bring the app to foreground, and even then, not all the time.
Any idea what's going wrong? Or my expectations incorrect?
How are you sending the app to the background? If you swipe to kill then your app won't automatically restart to receive the location events. I don't see it in your code, did you call requestAlwaysAuthorization? You might also want to implement LocationManager:didFailWithError just to see if that gives you any ideas.
My CLLocationManager starts when the user first enters the app. I am initializing it like this:
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = kDistanceFilter;
self.locationManager.headingFilter = kHeadingFilter;
And I am using geofencing.
I have defined in my .plist the required background modes.
If I test the app in the simulator using a gpx file, it works fine. So far, so good.
However, I read in these two links:
Start Location Manager in iOS 7 from background task
Background Location Services not working in iOS 7
That in iOS7, when the location does not change for a couple of minutes then the CLLocation goes to sleep.
My question is that:
I do not call didUpdateLocation at all, I only want the didEnterRegion, or didExitRegion. Theoretically, will it work , even the app is killed or user Location has not changed in the last hour and then decides to move?
There are a few elements in your questions:
1- In order not to rehash what is in a previous answer, I would first look at my answer at this link. It will help you resolve around the core location updates stopping if the user stops moving and how you can modify that behaviour:
iOS7 Core Location not updating
2- If the user kills an app in iOS7 (by flicking it up in the app switcher), the app will not restart and as such neither your location updates nor region monitoring will restart after the phone is restarted. On the other hand, if the app is killed because of memory pressures, iOS will restart the app and relaunch your location updates and region monitoring in the background. Also, if you reboot the phone, region monitoring will restart automatically. You obviously must have the background mode enabled.
3- Now you are talking about regions in your questions so I am assuming you have implemented CLCircularRegion. If not, that should be the first step and then "startMonitoringForRegion". In your case, even if the user has stopped moving for a while and then started moving, the app will be awaken/delegate called when the app enters or exit a region.
4- Make sure to use locationManager: didDetermineState: forRegion: as well. This will allow the app to determine if it is inside or outside of the region at start. This is useful when you think of an app being launched and no region crossing has happened but it is important to know whether the user is inside or outside of the region.
Hope this helps
I am failing to find any documentation on this. If my application is able to use background location services, how much processing can it really do before the device stops the task as its using too much resource?
E.g. When the location changes, I would like to ping my server with the new location.
Regards:
John
If an app has the permission of getting location updates in the background, then you are not limited on performing any tasks, so you could run any code, as the app is allowed to execute code while it is suspended (this is used by apps providing navigation).
However, be aware, that Apple will not approve your App, with the background Location updates permission, unless it's an App that would justify this requirement (Sports tracking App, Navigation App, etc)
You can get location updates from Region Monitoring or Significant Location changes, without having to use the location updates background mode.
So now comes the tricky part. Do I have enough time to perform a Server update of the users Location when my App is started from Background mode by the Region Monitoring or Significant Location services ?
The answer, seems to be yes, as suggested by this article
I haven't tried this, but judging by the code, I don't find a reason why this shouldn't work!
You will have to declare App’s Supported Background Tasks in info.plist
Under the information property list add array given format below:
Inforrmation Property list (Dictionary) ->
Required background modes (array) (1 item) ->
item 0 (String) - App registers for location updates
after these settings in info.plist you can do code which you want to do in background process at AppDelegate:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
/*
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
*/
self.locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
[_locationManager stopMonitoringSignificantLocationChanges];
[_locationManager startUpdatingLocation];
}
For more information you can visit:
Declaring Your App’s Supported Background Tasks