Get precise location every 1 minute in iOS 14 - ios

I am working on concept of guard application where in i need guard actual location every 60 seconds. same functionality was working in iOS 12, but in iOS 13 and 14 not working as it should be. i have made below changes for location manager.
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.distanceFilter = 2
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager.activityType = .other
locationManager.allowsBackgroundLocationUpdates = true
locationManager.pausesLocationUpdatesAutomatically = false
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
locationManager.startMonitoringSignificantLocationChanges()
am getting precise location when app is in foreground, but as soon as app goes background am not getting actual location. it would be great if any one can help me out as its causing the productivity of app and its basic usage.

Request the requestAlwaysAuthorization, if you are going to use the user’s location in the background.
let authorizationStatus = CLLocationManager.authorizationStatus()
if authorizationStatus == .authorizedAlways {
locationManager.startMonitoringSignificantLocationChanges()
} else {
locationManager.requestAlwaysAuthorization()
}
And also update the Info.plist:
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>

Please, make sure to read the documentation first.
Apart from setting the allowsBackgroundLocationUpdates to true, you also need to check the “Location updates” capability for your app in Xcode.
When a location update occurs while your app is in the background, the system launches your app and passes an options dictionary to the application(:willFinishLaunchingWithOptions:) or application(:didFinishLaunchingWithOptions:) methods. The dictionary may contain the location key to indicate that location services caused the app to launch.

Related

continuous iOS location updates in background

I am trying to create a simple iOS app that will continuously track location in the background and notify with high accuracy when the user has entered a specific region (don't want to use region monitoring because it's not accurate or fast enough for what I want).
This app works fine in the foreground but once I go into the background it does not work.
I created a test app to investigate how background location updates work. I made a simple app that just prints out a message when a location update happens (to the log).
What I see is that in foreground mode the updates happen as expected but when I lock my phone and the app switches to background the location updates happen for about 30 seconds and then stop. There is no mention in the Apple docs (that I can find) explaining this behavior.
I made sure that I enabled background processing in the info.plist (done in "capabilities" --> "background modes" --> "location updates")
Here is the code I used to test this:
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
let locationManager = CLLocationManager()
var counter = 0
override func viewDidLoad() {
super.viewDidLoad()
// configure location updates
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = 0.1
locationManager.pausesLocationUpdatesAutomatically = false
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("location updated! \(counter)")
counter = counter + 1
}
Any ideas on what I might be missing? I tried different location accuracy settings (such as BestForNavigation, etc) and no change.
Thanks.
You have to add this in your plist :
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
add this
locationManager.allowsBackgroundLocationUpdates = true
I think this might be the answer:
allowsBackgroundLocationUpdates.
Apps that want to receive location updates when suspended must include
the UIBackgroundModes key (with the location value) in their app’s
Info.plist file and set the value of this property to true.
...
The
default value of this property is false.
Are you setting that?
You can add these two line to make it working in background mode:
locationManager!.allowsBackgroundLocationUpdates = true
locationManager!.pausesLocationUpdatesAutomatically = false

Location updates stops in background - iOS

I am building an app for iOS that needs to know when the user is in a range of 20-30 meters of their home.
I user geofence to trigger an event when the user is 500m from their home, then I use CLLocationManager to start tracking the actual location and check distance to their home.
My problem is that when I call "startUpdatingLocation" from my geofence event while the app is in the background, it only runs for like 20 seconds and then stops giving any callbacks.
If I, after the 20 seconds have passed open the app and puts it back to the background then it keeps giving me callbacks until I stop it.
If I call "startUpdatingLocation" while the app is running and then puts it into the background, it keeps running as it should.
My code for initialisation looks like this:
init(config: AutounlockConfiguration) {
super.init()
self.config = config
self.locationManager = CLLocationManager()
self.locationManager.requestAlwaysAuthorization()
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.delegate = self
self.locationManager.pausesLocationUpdatesAutomatically = false
self.locationManager.allowsBackgroundLocationUpdates = true
self.locationManager.activityType = .automotiveNavigation
self.locationManager.distanceFilter = kCLDistanceFilterNone
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
}
and when I start updating location I do it like this:
func startFetchingUserLocation() {
if (!isFetchingLocation) {
isFetchingLocation = true
DanaDebugger.presentDebugPushMessage(message: "fetching new location")
locationManager.startUpdatingLocation()
}
}
I have enabled the background mode for location, and included the NSLocationAlwaysUsageDescription in my info.plist file.
I really have no clue where to go from here, hope somebody is able to help.
locationManager.startMonitoringSignificantLocationChanges()
Use this line instead of this line
locationManager.startUpdatingLocation()
it will solve your problem

Location permission check and authorization

I want my program to display the users location on the map. It was working at first then randomly stopped so i added the code below to try to fix it but I'm having problems. Thanks in advance!
override func viewDidLoad()
{
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
if CLLocationManager.locationServicesEnabled()
{
let status: CLAuthorizationStatus = CLLocationManager.authorizationStatus()
if status == CLAuthorizationStatus.NotDetermined
{
locationManager.requestAlwaysAuthorization()
}
} else {
print("locationServices disenabled")
}
locationManager.startUpdatingLocation()
self.locationManager.startUpdatingLocation()
self.mapView.showsUserLocation = true
mapView.delegate = self
centerMapOnLocation(initialLocation)
addBoundry()
}
You required to call,
locationManager.requestAlwaysAuthorization()
as well
locationManager.requestWhenInUseAuthorization()
to use location smoothly in foreground also!!!
and you should not need two instance to call startupdatinglocation. keep one. you should use instance or global variable instead of local to get location throughout the scope.
Update :
You have to set two keys in info.plist like, NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription with it's usage description.
If you want the "WhenInUse" notification you should only add "Privacy - Location When In Use Usage Description" in your info.plist but if you want the "Always" access your info.plist should look like this info.plist screenshot:
You don't have to add any request authorization like requestAlwaysAuthorization or requestWhenInUseAuthorization
I was having the same issue, even with NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescriptionset in info.plist. My debugger told me to also set NSLocationAlwaysAndWhenInUseUsageDescription...so I did it. It worked!
This is my code:
First import the library:
import CoreLocation
A little example:
let status: CLAuthorizationStatus = CLLocationManager.authorizationStatus()
if status == CLAuthorizationStatus.notDetermined || status == CLAuthorizationStatus.denied || status == CLAuthorizationStatus.restricted
{
locationManager?.requestAlwaysAuthorization()
}
And don`t forget to add these permissions in the Info.plist:

How to implement CLLocationManager.requestLocation() on iOS 8 or older?

If you have read the new iOS 9 docs, you may have noticed a new method which causes the location manager to power up radios for a brief amount of time, get a fix on your location and once desired accuracy (or timeout) is reached, turn it all back off, handing the pinpointed location over to the delegate.
The method is called CLLocationManager.requestLocation() and is available in the iOS 9 SDK. Alas, I'm currently working on an app targeting iOS 8 and would still very much like to make use of this method. I also wouldn't like to reimplement it all myself.
So here's my question: Is there any open-source library for iOS implementing this kind of one-time location retrieval?
You need to perform two steps first
1) NSLocationWhenInUseUsageDescription
2) NSLocationAlwaysUsageDescription
Then
var locationManager = CLLocationManager()
locationManager.delegate = self
// locationManager.locationServicesEnabled
locationManager.desiredAccuracy = kCLLocationAccuracyBest
let Device = UIDevice.currentDevice()
let iosVersion = NSString(string: Device.systemVersion).doubleValue
let iOS8 = iosVersion >= 8
if iOS8{
locationManager.requestWhenInUseAuthorization()
}
else{
locationManager.requestAlwaysAuthorization()
}
locationManager.startUpdatingLocation()
This will Help.Thanksyou
As Arslan Asim pointed out, a good solution would be to use INTULocationManager.
From the docs:
manager.requestLocationWithDesiredAccuracy(.Block, timeout: 10.0) {
(currentLocation, achievedAccuracy, status) in
// Examine status to see if the request timed out.
// If not, currentLocation stores the found location.
}

Unable to get the permission prompt from CLLocationManager

Here is my code from a ViewController implementing CLLocationManagerDelegate:
func startLocationManager() {
let locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
println("I'm called")
locationManager.requestAlwaysAuthorization()
// locationManager.startMonitoringSignificantLocationChanges()
locationManager.startUpdatingLocation()
let status = CLLocationManager.authorizationStatus()
println(status.rawValue) // This print 0 which stands for kCLAuthorizationStatusNotDetermined
println(CLLocationManager.locationServicesEnabled()) // true
}
func locationManager(manager: CLLocationManager!,
didUpdateLocations locations: [AnyObject]!) {
println("nobody call me ever, and I'm sad")
}
For some reason, I never get the prompt / alter to autorise location updates. I have tried on my device iOS 8.1 and the simulartor. I followed the advices found here: requestAlwaysAuthorization not showing permission alert :
"Add Core Location framework to Project Settings / Targets / Capabilities / Background Modes set "Location Updates" and "Uses Bluetooth LE Accessories" Add key at Info.plist NSLocationAlwaysUsageDescription".
I have also tried to clean up and rebuild, nothing change. I feel clueless.
EDIT: This question seems related: iOS: App is not asking user's permission while installing the app. getting kCLAuthorizationStatusNotDetermined every time - Objective-c & Swift but the selected answer and its article doesn't expose anything new
Your CLLocationManager object is local object and thus will be deallocated immediately after it falls out of scope. Make it a class property and then asynchronous processes like requesting authorization and determining the location will have a chance to run.

Resources