Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

xArtx

macrumors 6502a
Original poster
Mar 30, 2012
764
1
Hi Guys,
Small problem.. I'm checking for both conditions,
Location Services are globally disabled,
or Location Services were not authorised for the App.

I use this code straight after enabling Location Services in the App.

Code:
    if (![CLLocationManager locationServicesEnabled]) {errorcode = 1;}
    if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) {errorcode = 1;}
        
    if (errorcode == 1) {
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Location Services"
                                              message:@"Functionality of this program is limited to Map Browse Mode without Location Services enabled."
                                              delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
    [alert show];     
    }

So if "errorcode" is set to 1 I can go about handling the absence of core location.
Problem is, every time I delete the App from a device, and run it for the first time,
I can deny the App's permission to use Location Services, and errorcode
is not set to 1, and the alert doesn't show, and Location Services are not working.
The second time I run the App, all is well. The alert does show,
and error code is set to 1.

Any ideas what I'm doing wrong?
Surely if this was an Apple bug it would have been sorted by now.
Cheers, Art.
 

ArtOfWarfare

macrumors G3
Nov 26, 2007
9,563
6,060
Use the debugger. Is any of this code being executed on the first launch at all? If not, why not? From where is the method you shared with us being called?
 

xArtx

macrumors 6502a
Original poster
Mar 30, 2012
764
1
Yes, because the error handling is straight after starting corelocation:
Code:
  self.locationManager = [[CLLocationManager alloc] init];
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    locationManager.delegate = self;
    [locationManager startUpdatingHeading];    
    [locationManager startUpdatingLocation];

and that always works if I allow it.

I was looking at the docs, and found that kCLAuthorizationStatusDenied
or granted are not the only results.
There is a result that means "not known yet".
It might do to sit in a while loop until it gives a straight answer.

I have found through testing, that the old fashioned way (pre 4.xx) :
Code:
-(void)locationManager:(CLLocationManager *)manager 
      didFailWithError:(NSError *)error
{
errorcode = 1;
}

can report an error for reasons other than core location wasn't granted.
It failed on me once when I resumed the App, where location services were never denied either globally, or for the App.
 

xArtx

macrumors 6502a
Original poster
Mar 30, 2012
764
1
Careful, you might end up blocking the main run loop, which might prevent the user from being able to respond to the prompt to grant or deny access.

Yep, that happened. It never leaves the boot screen, and the prompt never arrives.
I'll have to allow it to pass, and just keep checking until I see a result I want.

So basically, never do this:
Code:
    while ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
    int cccvvv = 0; // waste a bit of time
    cccvvv++;
    if (cccvvv > 100) {cccvvv = 0;}
    } // not yet determined


But that makes me pretty sure the value is kCLAuthorizationStatusNotDetermined.

----------

And interestingly, this is called after you select OK or Do Not Allow.
Only for the first launch.
But the App is working and refreshing frames while the prompt is up.

Code:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
    resumed = 1;
    // 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.
}
 

dejo

Moderator emeritus
Sep 2, 2004
15,982
452
The Centennial State
Yes, because the error handling is straight after starting corelocation

As stated in the CLLocationManager Class Reference, you should be checking if the desired services are available before you instantiate your CLLocationManager.

And have you looked into CLLocationManagerDelegate's locationManager:didChangeAuthorizationStatus: method yet?

Also, by the way, you still haven't told us where (i.e. in which method/class) you are running any of the provided code.
 

xArtx

macrumors 6502a
Original poster
Mar 30, 2012
764
1
It does seem to be working as expected now :)

I was initially starting it in viewdidload, but moved it to my main loop when
I decided to distribute it.. so I can try to restart it.

I know when the program is resumed,
so I suppose I can check for authorisation change there.
If the App is resumed, I pause track logging to give the device a chance to
get a good quality position before the log is ruined with poor locations.

I suppose I should check location services are available for the device,
even though I plan to require GPS in plist settings. Then it's there if I change
my mind about that for an update.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.