CLLocationManager and tvOS - RequestWhenInUseAuthorization() not prompting - swift

I seem to be having a little trouble getting tvOS to prompt the user for location data authorization. I literally copied and pasted working code from iOS and it seems to not be prompting the user. I am using the code listed below as well as the NSLocationWhenInUseUsageDescription key with a string value. The only difference in the api that I see is on iOS it uses startupdatinglocation() and on tvOS it uses requestLocation() (similar to watchOS) I've stepped through the problem and it is infact hitting requestWhenInUseAuthorization() but simply doesn't prompt the user.
Any idea what is going on?
import UIKit
import CoreLocation
class ViewController: UIViewController {
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
if CLLocationManager.locationServicesEnabled(){
if CLLocationManager.authorizationStatus() == CLAuthorizationStatus.NotDetermined{
locationManager.requestWhenInUseAuthorization()
}
else if CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedWhenInUse{
locationManager.requestLocation()
}
}
}

It turns out that a CFBundleDisplayName key and $(PRODUCT_NAME)value is needed in order for the prompt to display.

Related

How to check location authorization status at the click of a button in iOS 14?

How can I use Core Location's locationManagerDidChangeAuthorization(_:) method to check authorization status and report user location at the press of a button (called in #IBAction) below:
My issue here is that when I run the code in the simulator, CoreLocation doesn't pop up with an alert to ask the user for permission when the button is pressed.
class CurrentLocationViewController: UIViewController, CLLocationManagerDelegate {
let locationManager = CLLocationManager()
// Button to check authorization status and start sending location update to the delegate
#IBAction func getLocation() {
locationManagerDidChangeAuthorization(locationManager)
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
// Delegate method to check authorization status and request "When In Use" authorization
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
let authStatus = manager.authorizationStatus
if authStatus == .notDetermined {
locationManager.requestWhenInUseAuthorization()
return
}
}
EDIT: Using the deprecated authorizationStatus() class method in the #IBAction method instead of the locationManagerDidChangeAuthorization(_:) method allows me to get the pop up when the button is pressed in the simulator. I'm still trying to figure out why this modification works whereas my code above doesn't.
#IBAction func getLocation() {
let authStatus = CLLocationManager.authorizationStatus()
if authStatus == .notDetermined {
locationManager.requestWhenInUseAuthorization()
return
}
...
You're code works - but have you remembered to add the privacy usage descriptions to the info.plist file?
Add these two entries in the file with your own explanation in the value field, then it should popup in the simulator:
Privacy - Location Always and When In Use Usage Description
Privacy - Location When In Use Usage Description

OS X save location permission

I'm getting the users GPS Location like this:
var manager:CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
manager = CLLocationManager()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.startUpdatingLocation()
//manager.requestAlwaysAuthorization()
//manager.requestWhenInUseAuthorization()
}
func locationManager(manager:CLLocationManager, didUpdateLocations locations: [AnyObject]) { // Updated to current array syntax [AnyObject] rather than AnyObject[]
println("locations = \(locations)")
}
The commented-out functions seem not to exist for os x applications. It still works for me so that's fine.
But every time I run the code it asks for permission to use location.
Is it possible to store the permission somewhere, so it only asks on the first execution?
Quoting Apple's documentation:
Call the authorizationStatus class method to get the current authorization status for your app.
If the authorization status is kCLAuthorizationStatusRestricted or kCLAuthorizationStatusDenied, your app is not permitted to use location services and you should abort your attempt to use them.
Your code on OS X should look like this:
override func viewDidLoad() {
super.viewDidLoad()
let status = CLLocationManager.authorizationStatus()
if status == .Restricted || status == .Denied {
// User permission not given
return
}
manager = CLLocationManager()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.startUpdatingLocation()
}
Permission is managed centrally by Mac OS X. The first time you call startUpdatingLocation, it will ask for permission then remembers what the user has decided.

Find out if statUpdatingLocation is active in Swift

I have a location based app running in swift. I am trying to detect if the self.locationManager.startUpdatingLocation() is currently active.
I am struggling to find out how to do this nor can I find much on the internet about it. This I am fairly sure is rather simple to achieve. I don't want to set a BOOL as this needs to be global.
if CLLocationManager.locationServicesEnabled() && /* START UPDATE LOCATION GOES HERE */ {
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestAlwaysAuthorization()
self.locationManager.startUpdatingLocation()
//self.locationManager.startMonitoringSignificantLocationChanges()
sender.setTitle("END DAY", forState: UIControlState.Normal)
} else {
}
I know this is a late answer now. But this is possibly one solution if you want to know if the locationManager is updating.
There should only be one instance of CLLocationManager in your app. So creating a Singleton is ideal. Then, you should override the methods startUpdatingLocation and stopUpdatingLocation.
(Swift 3)
import CoreLocation
class LocationManager: CLLocationManager {
var isUpdatingLocation = false
static let shared = LocationManager()
override func startUpdatingLocation() {
super.startUpdatingLocation()
isUpdatingLocation = true
}
override func stopUpdatingLocation() {
super.stopUpdatingLocation()
isUpdatingLocation = false
}
}
Usage:
if LocationManager.shared.isUpdatingLocation {
print("Is currently updating location.")
} else {
print("Location updates have stopped.")
}
You cannot not know whether startUpdatingLocation() is "active" because you are the one who said it.
If you need to keep track of this from elsewhere, make a Bool property and set it to true when you call startUpdatingLocation() and to false when you call stopUpdatingLocation().

Not ask permission to access to coreLocation and crash in swift

I have CoreLocation in my Swift app. When I run this in simulator or in a device, this crash and not show the permissions to access CoreLocation.. I have all code necessary to implement this: request in code, NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription in plist...
I'm reading iOS app doesn't ask for location permission but I can't make that this show.
var location: CLLocationManager!
let status = CLLocationManager.authorizationStatus()
location=CLLocationManager()
if(status == CLAuthorizationStatus.NotDetermined) {
self.location.requestAlwaysAuthorization();
}
else {
location.startUpdatingLocation()
}
location.delegate = self
location.desiredAccuracy=kCLLocationAccuracyBest
self.location.startMonitoringSignificantLocationChanges()
print(location.location.coordinate.latitude) //Here crash
print(location.location.coordinate.longitude)
What other things can I make for show this?
Thanks!
Here is a code snippet from my app:
let locationManager = CLLocationManager()
...
locationManager.delegate = self
locationManager.activityType = CLActivityType.Fitness
locationManager.distanceFilter = 10 // 10m
if ( UIDevice.currentDevice().systemVersion == "8.0" ) {
locationManager.requestAlwaysAuthorization()
}
// get current location
if CLLocationManager.authorizationStatus() == CLAuthorizationStatus.Authorized {
locationManager.startUpdatingLocation()
}
The prompt only shows if the status is .NotDetermined. There are other statuses though that would prevent the location services from working (all but .Authorized) when the prompt does not get displayed. You should check for these.
Also, the requestAlwaysAuthorization does not return immediately and you need to implement
func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus)
You have to add a row to info.plist file
NSLocationWhenInUseUsageDescription which contains a string.
That string will be displayed when the alert pops up asking user's permission.

Core Location in Swift

This is sample code. NSLocationAlwaysUsageDescription key in Info.plist installed. All work fine - program receives the coordinates.... displays them.....
And it continues to update them permanently! In the case of the iOS simulator - it is not critical, but in the case of a real application it is very quickly drain the battery. How to make an application launched Core Location, received location, and got shut down Core Location?
import UIKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
#IBOutlet var locLabel: UILabel
#IBOutlet var latLabel: UILabel
#IBOutlet var lonLabel: UILabel
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func locButton(sender: AnyObject) {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(manager:CLLocationManager, didUpdateLocations locations:AnyObject[]) {
println("locations = \(locationManager)")
var latValue = locationManager.location.coordinate.latitude
var lonValue = locationManager.location.coordinate.longitude
latLabel.text = String(latValue)
lonLabel.text = String(lonValue)
locLabel.text = "success"
}
}
If you are not much concern about high level of accuracy then you should consider startMonitoringSignificantLocationChanges instead of startUpdatingLocation. It will really make a big difference in battery draining.
This method is more appropriate for the majority of applications that just need an initial user location fix and need updates only when the user moves a significant distance. This interface delivers new events only when it detects changes to the device’s associated cell towers, resulting in less frequent updates and significantly lower power usage.
For more detail you can take a look over CLLocationManager Guide