I have an app that I am trying to get the authorization for LocationManager to show up. I had it working for Always but then tried When In Use. Now I can't get either one to work
I have Placed
NSLocationWhenInUseUsageDescription string enable to play
in my Info.plist
In my app delegate I have put
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.locationManager = [[CLLocationManager alloc]init];
self.locationManager.delegate= self;
return YES;
}
- (void)locationManager:(CLLocationManager *)manager
didChangeAuthorizationStatus:(CLAuthorizationStatus)status{
if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusAuthorized){
NSLog(#"ok");
}
if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusAuthorizedAlways){
NSLog(#"Always");
}
if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusAuthorizedWhenInUse){
NSLog(#"WhenInUse");
}
if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusRestricted){
NSLog(#"restricted");
}
if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusDenied){
NSLog(#"denid");
AlertView2 = [[UIAlertView alloc] initWithTitle:#"App Permission Denied"
message:#"Please go to Settings/Privacy/Location Services to enable Always for this app to function properly."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[AlertView2 show];
}
if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusNotDetermined){
NSLog(#"undetermined");
[self.locationManager requestWhenInUseAuthorization];
}
}
I'm not sure this is what I had originally but I have tried every possible configuration, although obviously not.
Can someone help me get this thing working. I would prefer WhenInUse but at this point I'll take anything
By the way I do get a call back of the NSLog undetermined in the last status but the included code is not called.
Thanks for any help.
A couple of thoughts:
I'd suggest setting the delegate before you request permission.
What is authorizationStatus before you request permission? You should check it before you bother to request permission, because if they already refused permission, you want to tell them to fix settings. A request for permission will not result in anything (including a change in status) if permission was previously denied.
Try This .....
locationManager = [[CLLocationManager alloc]init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = 1000.0f;
[locationManager requestAlwaysAuthorization];
[locationManager requestWhenInUseAuthorization];
[locationManager startUpdatingLocation];
So I am officially an idiot.
I looked at my info.plist and there it was. I had copied and pasted the Alway Description and changed it to WhenInUse and the when it didn't work I deleted the original and kept the copy and changed it back to Always. However upon expanding the column to see the whole thing the was a -2 attached to the end so it wasn't formatted correctly so it didn't work. Once I removed the -2 it works wonderful. I have changed the original post to show how it works. Thanks for all your help and I will make sure I address the concern you brought up.
Related
I'm working on permissions for location, problem is next:
User turned off location services from privacy and installed the app. I have line of code that is asking to enable location services: if (![CLLocationManager locationServicesEnabled] || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied)... and this is working pretty fine. Problem is that app don't ask for allowing app to use location, then it asks the second time. Code for asking for permission:
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
NOTE: Everything works fine if locations services enabled, it asks for approval first time.
EDIT: Full code for permissions:
-(void)setupPermissions
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
if (![CLLocationManager locationServicesEnabled] || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) {
}
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
}
Your code makes no sense. You have this:
if (something) {
}
if (somethingelse) {
[self.locationManager requestWhenInUseAuthorization];
}
So you have one if that is empty, and another if that always runs regardless of what the first if does. Perhaps you meant to use else if for the second condition?
(And keep in mind that, as you've already been told, calling requestWhenInUseAuthorization is pointless unless the status is NotDetermined.)
The only time you can get iOS to request user permissions is when the authorization status is NotDetermined.
If a user has denied your app, the only way you can get them to be prompted again is to uninstall the app, or reset privacy on the device.
The easiest approach would be to provide an alert controller with a link to settings so that they can turn it on themselves.
Here is a link that shows the process for doing that.
I am trying to get authorization from user before fetching his location. I am using this code for that:
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager setDelegate:self];
if ([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
// iOS8+
// Sending a message to avoid compile time error
[self.locationManager requestAlwaysAuthorization];
}
[self showIndicatorView];
self.getCityService = [[GetCitiesService alloc] initServiceWithDelegate:self isLocalCall:NO];
[self.getCityService fetchCities];
I see the alert on screen but before I allow it or not, it disappear form screen and app is not authorized.
I want my code to stop until user gives permission.
Apparently in iOS 8 SDK, requestAlwaysAuthorization (for background location) or requestWhenInUseAuthorization (location only when foreground) call on CLLocationManager is needed before starting location updates.
There also needs to be NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription key in Info.plist with a message to be displayed in the prompt. Adding these solved my problem.
Hope it helps someone else.
EDIT: For more extensive information, have a look at: http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/
You code looks really weird, since you seem to be calling the requestAlwaysAuthorization twice. Once on self.locationManager and once via the sendAction.
You code should look like:
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager setDelegate:self];
if ([self.locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
// iOS8+
// Sending a message to avoid compile time error
[self.locationManager requestAlwaysAuthorization];
}
I'm asking this because I'm a bit confused. I did set NSLocationAlwaysUsageDescription in my Info.plist and this is the code I'm running:
CLLocationManager *locMan = [[CLLocationManager alloc] init];
locMan.delegate = self;
if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorizedAlways)
{
[locMan requestAlwaysAuthorization];
}
[locMan startUpdatingLocation];
I set a breakpoint and verified that this does indeed get called, but I am not alerted in the app. I check in my privacy settings and saw the app had an entry with the two options: None and Always, with neither checked. I tried to uninstall, clean, and reinstall, but still is not working. Any ideas?
EDIT:
I moved the above block from viewDidLoad into viewDidAppear: and now the alert comes up and disappears half a second later
I solved my issue. It's a retain issue. I was declaring my CLLocationManager locally, so when it reached the end of my method, it would didn't exist anymore, which explains why it couldn't ask for permission. I promoted it to be a property and now all works well
You need to add this line at the end of your code
[self.locationManager startUpdatingLocation];
What about if you try this:
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
if ([locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[locationManager requestWhenInUseAuthorization];
}
[locationManager startUpdatingLocation];
Sorry, missread your post. Maybe try this:
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusAuthorizedWhenInUse || status == kCLAuthorizationStatusDenied) {
// Show alert or something
}
else if (status == kCLAuthorizationStatusNotDetermined) {
[self.locationManager requestAlwaysAuthorization];
}
More can be read here: Core Location Manager Changes in iOS 8
I am using iBeacons, but am running into a small problem.
On first use the user needs to give permission, we then following is called:
_locationManager = [[CLLocationManager alloc] init];
_locationManager.delegate = self;
[_locationManager requestAlwaysAuthorization];
However, I expected the following delegate method to be called:
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
NSLog(#"Auth status changed: %i", status);
if(status > 3){
// Check if we have to start monitoring beacons
NSLog(#"Do we need to initialise after auth given?");
//[self initialiseLocations];
}
}
I am running iOS 8.0.2, so not sure if this is a bug
This answer might help... it solved it for me at least. Also this website was a good walkthrough for this issue as well.
It looks like you are calling the requestAlwaysAuthorization correctly, but do you call startUpdatingLocation anywhere? Also, double check that in your Info.plist you have the appropriate key and string value added (NSLocationAlwaysUsageDescription since you're using requestAlwaysAuthorization).
Spent few days trying to solve this but unable to find any solutions that works. I have checked all the post on stackoverflow and tried all their solutions and nothing seems to be working for. I have also tried the apple test project for CLLocation which works fine for me. I used bits and pieces from the apple test project
https://developer.apple.com/library/ios/samplecode/LocateMe/Listings/README_md.html
But my code is not working at all. The DidupdateToLocation never gets called.
Here is my code (in viewDidLoad)
_locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// This is the most important property to set for the manager. It ultimately determines how the manager will
// attempt to acquire location and thus, the amount of power that will be consumed.
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// Once configured, the location manager must be "started"
//
// for iOS 8, specific user level permission is required,
// "when-in-use" authorization grants access to the user's location
//
// important: be sure to include NSLocationWhenInUseUsageDescription along with its
// explanation string in your Info.plist or startUpdatingLocation will not work.
//
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
[self performSelector:#selector(stopUpdatingLocationWithMessage:)
withObject:#"Timed Out"
afterDelay:30];
I have checked to make sure locationServicesEnabled is enabled.
I have added NSLoationWhenInUseUsageDescription property to the info.plist file. Is there any other property I need to add or enable any services??
I cannot for the love of god figure out what i have done wrong. Can some one please help me with this.
You have to call the startUpdatingLocation after you received the didChangeAuthorizationStatus callback on iOS8.
//iOS 8 API change
if([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]){
[self.locationManager requestWhenInUseAuthorization];
}else{
[self.locationManager startUpdatingLocation];
}
implement this delegate method:
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
switch (status) {
case kCLAuthorizationStatusNotDetermined:
case kCLAuthorizationStatusRestricted:
case kCLAuthorizationStatusDenied:
{
// do some error handling
}
break;
default:{
[self.locationManager startUpdatingLocation];
}
break;
}
}
First, don't forget, with IOS 8 you need to do [locationManager requestWhenInUseAuthorization] plus [locationManager requestAlwaysAuthorization];
_locationManager = [CLLocationManager new];
if(SYSTEM_IS_OS_8_OR_LATER) {
[_locationManager requestWhenInUseAuthorization];
[_locationManager requestAlwaysAuthorization];
}
_locationManager.delegate = self;
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
//and the problem with your code : don't forget to start
_locationManager startUpdatingLocation];
and in your didUpdateLocations
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
_currentLocation = [locations objectAtIndex:0];
//do your stuff with the location
}
Silly me. I added the keywords to the wrong plist file. I have got it working now. Thanks for your help guys.
I just spend an entire morning on this [in honestly I am relative new OOC], anyway the problem..
didUpdateLocation compiles and is never called
didUpdateLocations compiles and does work!!
Not the answer in this case it would seem, but it is in the question, an easy mistake to make. Using IOS 8.1.3 & Xcode 6.1.1
Simply add three properties in Info.plist.
To get the current location, if it is not calling didUpdateToLocation method
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
privacy - location usage description of type String.