I am just creating an iOS app that needs to get the user location.
I have included the needed keys and values into info.plist like shown in the screenshot:
but when running the app there is a message in the debugger:
2020-04-25 18:51:16.395466+0200 Jogua[23008:1151035] This app has attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain both “NSLocationAlwaysAndWhenInUseUsageDescription” and “NSLocationWhenInUseUsageDescription” keys with string values explaining to the user how the app uses this data
Do I need to change anything else in the code?
EDIT
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
determineMyCurrentLocation()
}
func determineMyCurrentLocation() {
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation:CLLocation = locations[0] as CLLocation
print("user latitude = \(userLocation.coordinate.latitude)")
self.defaults.set(userLocation.coordinate.latitude, forKey: "mi_latitud")
print("user longitude = \(userLocation.coordinate.longitude)")
self.defaults.set(userLocation.coordinate.longitude, forKey: "mi_longitud")
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error)
{
print("Error \(error)")
}
As your debugger says, you are missing one entry in your info.plist. It can be misleading because the name the console prints, is not the actual key name inside info.plist.
You added:
Privacy - Location Always Usage Description
Privacy - Location Usage Description
Privacy - Location Always and When In Use Usage Description
What you need according to the debugger is:
Privacy - Location When In Use Usage Description
Privacy - Location Always and When In Use Usage Description
What you need to add in your case:
Privacy - Location When In Use Usage Description
Related
I Had these errors while writing a map in xcode:
2021-01-09 19:02:48.228694+0100 BudapestBoards[31795:558225] Metal API Validation Enabled
2021-01-09 19:02:48.433777+0100 BudapestBoards[31795:558225] This app has attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an “NSLocationWhenInUseUsageDescription” key with a string value explaining to the user how the app uses this data
2021-01-09 19:02:50.483788+0100 BudapestBoards[31795:558499] [MKCoreLocationProvider] CLLocationManager(<CLLocationManager: 0x600002b2b5b0>) for <MKCoreLocationProvider: 0x600001b30360> did fail with error: Error Domain=kCLErrorDomain Code=1 "(null)"
CoreSimulator 732.18.6 - Device: iPhone 12 Pro Max (B1F529FE-C1E7-4C0A-B918-A3C76E006F27) - Runtime: iOS 14.3 (18C61) - DeviceType: iPhone 12 Pro Max
i am using mapview.
my code is:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
let manager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.delegate = self
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.first {
manager.stopUpdatingLocation()
render(location)
}
}
func render(_ location: CLLocation) {
let span = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
let coordinate = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let region = MKCoordinateRegion(center: coordinate, span: span)
mapView.setRegion(region, animated: true)
}
}
}
Thanks for responding when adding a NSLocationWhenInUseUsageDescription it says it is already present in the dictionary and if i want to replace it. if i press on replace it does not do anything except delete that line.
The relevant information in this error is:
This app has attempted to access privacy-sensitive data without a
usage description. The app's Info.plist must contain an
“NSLocationWhenInUseUsageDescription” key with a string value
explaining to the user how the app uses this data
You need to provide a string in your Info.plist that explains why your app wants to access location information.
So locate the Info.plist file, add a new line with "NSLocationWhenInUseUsageDescription" as key and a text. The text is presented in the alert which asks the user, whether he allows access or not, so consider localising it.
SITUATION:
I followed the following tutorial:
https://www.raywenderlich.com/95014/geofencing-ios-swift
PROBLEM:
The following functions never get triggered:
AppDelegate.swift
func locationManager(manager: CLLocationManager, didEnterRegion region: CLRegion) {
if region is CLCircularRegion {
handleRegionEvent(region)
}
}
func locationManager(manager: CLLocationManager, didExitRegion region: CLRegion) {
if region is CLCircularRegion {
handleRegionEvent(region)
}
}
func handleRegionEvent(region: CLRegion!) {
print("Geofence triggered!")
// Show an alert if application is active
if UIApplication.sharedApplication().applicationState == .Active {
if let message = notefromRegionIdentifier(region.identifier) {
if let viewController = window?.rootViewController {
showSimpleAlertWithTitle("Congratulations", message: "You just found: " + message , viewController: viewController)
}
}
} else {
// Otherwise present a local notification
let notification = UILocalNotification()
notification.alertBody = "You just found: " + notefromRegionIdentifier(region.identifier)!
notification.soundName = "Default";
UIApplication.sharedApplication().presentLocalNotificationNow(notification)
}
}
QUESTION:
The tutorial was written for iOS 8. I am currently on iOS 9.3. What caused this issue in your opinion and how do I fix it ?
You didn't show the code that you use to set up CL - which is probably where your problem lies.
Did you edit info.plist?
Are you requesting permission?
Did you call one of the start functions on the CL manager?
Make sure of two things :-
1.) You have added These to your viewDidLoad() :-
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.requestWhenInUseAuthorization()
locationManager.startMonitoringSignificantLocationChanges()
locationManager.startUpdatingLocation()
Another alternative to requestWhenInUseAuthorization() and startUpdatingLocation() initialisation in specific to Swift 2.2, since in Swift 2.2 the string literals for selectors is deprecated, and instead there this new operator #selector that you need to be using. :-
you can also use :-
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.startMonitoringSignificantLocationChanges()
if locationManager.respondsToSelector(#selector(locationManager.requestWhenInUseAuthorization)) {
locationManager.requestWhenInUseAuthorization()
}
else {
locationManager.startUpdatingLocation()
}
//Prefer the FIRST ONE.
2.) You have updated your info.plist with :-
NSLocationAlwaysUsageDescription : String :-> I need location.
NSLocationWhenInUseUsageDescription: String :-> I need location.
privacy - location usage description: String :-> I need location.
Edit I need location according to the app's need
PS :- If it still not calls your locationManager functions
Simulator :- look for location settings of your app in your simulator settings.
Device: - Go in settings > Privacy > Location services > Your app > Always.
you also might find this explanation useful : - https://stackoverflow.com/a/26090094/6297658
initialize your location manager in app delegate on did finish launching
Yeah ! My CoreLocation working now ! So i have a problem to store latitude and longitude and stopping locating.
I have a Sign In page (my MainVC)
before user sign in i need to get and store current device location and stop locating (now it's working with help of Alexander see under).
in my MainVC.swift i have this 2 global variables
var locationManager:CLLocationManager!
var myLocations = [CLLocation]()
in my viewDidLoad() i have this :
//Setup our Location Manager
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
For operate locationManager i have this 2 functions :
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("locations = \(locations)")
errorMsgIfInternetNotAvailable.text = "GPS success"
myLocations.append(locations.last!)
locationManager.stopUpdatingLocation()
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
errorMsgIfInternetNotAvailable.text = "Error while updating location " + error.localizedDescription
}
When i build my app, all working, if not autorise my device to get GPS informations i have the locationManager function error working.
If i autorise it
in console, the location update every second and don't stop it with the .stopUpdatingLocation() command
First, it is always good to provide the build error output. It's hard enough to guess which error you're getting.
It seems like you defined, but not initialized myLocations property. You have to do it like this:
var myLocations = [CLLocation]()
Notice the brackets () in initialization.
And then you have to add object to your array:
myLocations.append(locations.last)
or, if you want to store only one object in your array, do it like:
myLocations = [locations.last]
my viewController looks like following
import CoreLocation
class MyViewController: UIViewController {
let locationManager = CLLocationManager()
override func viewDidAppear(animated: Bool) {
if #available(iOS 8.0, *) {
self.locationManager.requestWhenInUseAuthorization()
} else {
// Fallback on earlier versions
}
if (CLLocationManager.locationServicesEnabled()) {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
let lon = locationManager.location!.coordinate.longitude
let lat = locationManager.location!.coordinate.latitude
print("lat = \(lat) and long = \(lon)")
}
}
}
// MARK: - CLLocationManagerDelegate
extension MyViewController : CLLocationManagerDelegate {
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
self.locationManager.stopUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print("\(error.localizedDescription)")
}
}
When I execute my program, it prompts a message like
Allow application to access your location while you use the app?
But the Don't Allow and Allow buttons are disabled.
Can someone guide me on where I am going wrong and what I should be doing.
I can manually allow my application to access location services by going to settings. But I would like to know why the buttons are disabled and what should I do to enable it.
note: I have added NSLocationWhenInUseUsageDescription to my info.plist file.
Thanks.
Dt: 29Oct2015
EDIT:
Uninstalled the app and installed again and tried. Now I am able to access the buttons.
Also, I noticed that sometimes the screen goes unresponsive i.e., screen cannot take any input from user. I noticed it today with a textbox. I am not able to get the cursor to the text box.
Is it something to do with IOS update? is anyone else experiencing this type of weird behaviour. Is there any workaround for the same?
Any help is highly appreciated.
Thanks.
My code is included below. It's a class intended to return the current location coordinates. The only output I get is "before after before after" - the print lines surrounding requestAlwaysAuthorization. And then the App crashes. The request dialog sometimes shows briefly, sometimes for a few seconds. On few occasions I even get to press "OK". The App always crashes. I've had this problem in xCode 7.0 and now xCode 7.0.1, iOS 9.0 in both cases. I have searched StackOverflow high and low, and most questions on this topic are for earlier versions of both xCode and iOS, and none of the posted solutions helped in my case. Hence, this question. I've also found YouTube tutorials that do basically what I'm doing, but no joy. I also have NSLocationAlwaysUsageDescription in my plist, and I have Privacy - Location Usage Description and NSLocationWhenInUseUsageDescription for good measure. I have also tried sending a location from xCode via the Product\Scheme menu, and I have also tried using the simulator's Debug\Location. I've tried a few different location options for each. The simulator's Map app always seems to work. And Apple's LocateMe (written in Objective C) also works. Swift 2 (my code below) fails.
import CoreLocation
class TheCurrentLocation: NSObject, CLLocationManagerDelegate {
var locationManager: CLLocationManager!
var latitude: Double = 0
var longitude: Double = 0
var locationStatus: NSString = "Not Started"
func initialize() {
self.locationManager = CLLocationManager()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
print("before")
self.locationManager.requestAlwaysAuthorization()
// self.locationManager.requestWhenInUseAuthorization()
print("after")
} // END: initialize()
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
self.locationManager.stopUpdatingLocation()
print("ERRORS: " + error.localizedDescription )
} // END: locationManager delegate didFailWithError
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
self.locationManager.stopUpdatingLocation()
print ("ta da")
self.latitude = center.latitude
self.longitude = center.longitude
} // END: locationManager delegate didUpdateLocations
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
var isAllowed = false
switch status {
case CLAuthorizationStatus.Restricted:
locationStatus = "Restricted Access to Location"
case CLAuthorizationStatus.Denied:
locationStatus = "User Denied Access to Location"
case CLAuthorizationStatus.NotDetermined:
locationStatus = "Location Status Not Determined"
default:
locationStatus = "Allowed Access to Location"
isAllowed = true
} // END switch status
if (isAllowed == true) {
NSLog(String(locationStatus))
self.locationManager.startUpdatingLocation()
} else {
NSLog(String(locationStatus))
}
} // END: locationManager delegate didChangeAuthorizationStatus
} // END: theCurrentLocation
I think I know what may be causing it. You cant have both NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription. Only one of them. I think I ran into this problem before. Try to remove one of them and see if that fixes it.