CLLocation Manager not prompting user - iphone

I am using a method to create a location manager if it doesn't exist and start it. It checks if the user has location services disabled and respects that unless a BOOL is given to start the services anyway. The method returns a BOOL to indicate services have been started or not.
This works fine for starting the service and prompting the user the first time. If they tap allow things proceed as normal and if they tap don't allow I present a view to input location manually.
However I would like the user to be able to change their mind about using location services so I have a button to allow them to go back to using GPS. It calls the same function again, but this time ignores the users location services preference. I believe this should prompt the user to allow/disallow again, but I am getting an immediate kCLDenied error code instead.
Based on http://developer.apple.com/iphone/library/documentation/UserExperience/Conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html#//apple_ref/doc/uid/TP40009497-CH2-SW11 I would expect another user prompt, not an immediate error.
- (BOOL)startLocationServices:(BOOL)ignorePrefs
{
//
// /*UNREVISEDCOMMENTS*/
//
if (locationManager == nil)
{
if ([CLLocationManager locationServicesEnabled] || ignorePrefs)
{
locationManager = [[CLLocationManager alloc] init];
[locationManager setDelegate:self];
[locationManager setDesiredAccuracy:kCLLocationAccuracyNearestTenMeters];
[locationManager setDistanceFilter:10.0];
}
else
{
return NO;
}
}
[locationManager startUpdatingLocation];
return YES;
}
(My location manager delegate releases and sets location manager to nil if a denied error is received.)

The user will not receive another prompt message. It just the way the iPhone handle things.
You also have to differentiate between:
User disable location services from the Settings application (this status is returned by the + (BOOL)locationServicesEnabled
method)
User declined usage of the location tracking for the current app (+ (CLAuthorizationStatus)authorizationStatus method returns the current status)
I would check both methods and in case show an alertview with a message, about deactivated location services.

Related

Allow location service in iPhone

i am making an app in which I want user's location. I am using this code -
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
If user's don't allow there location then next time when user's open app then I am using this code for allow user's location -
if([CLLocationManager locationServicesEnabled] &&
[CLLocationManager authorizationStatus] != kCLAuthorizationStatusDenied)
{
NSLog(#"enable");
}
else {
NSLog(#"disable");
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"prefs:root=LOCATION_SERVICES"]];
}
But this is not work in iOS SDK 5.1 . So I want that every time when app become in foreground then if location service is disable then how to gave pop up of Allow location service.
The settings app URL scheme is not longer available, you will just have to present the user with an UIAlertView or present a UIViewController modally that tells the user to switch on the location services for your app.
You can't really force the allow location dialog, it just pops up the first time.

Location Based Notifications are not calling in suspend mode

I am new to location based applications.
My requirement is, device has to show the location based notifications when the user reaches the selected region.
I implemented perfectly. This app is working on background also.
Now my new requirement is, device has to show the location based notifications even after kill the app. [I saw a couple of iPhone apps working with this functionality. The apps are "Reminder" & "Locationizer" ] .
Can you please check my implementations steps as follows.
Launch the application.
Selected the location alert button.
Called the following CLLocationManager API's to monitor my region.
[locationManager startMonitoringForRegion:#"MyRegion" desiredAccuracy:kCLLocationAccuracyBest];
[locationManager startMonitoringSignificantLocationChanges];
Quit the app [Running in background].
I am getting location based alert notifications properly.
Here the new requirement.
Launch the application.
Selected the location alert Button.
Called the following CLLocationManager API's to monitor my region.
[locationManager startMonitoringForRegion:#"MyRegion" desiredAccuracy:kCLLocationAccuracyBest];
[locationManager startMonitoringSignificantLocationChanges];
Kill the app. [now application is not running in background]
App should show the location based notification when user reach the location.
How do I implement this logic?
Hi Friends I found solution for this issue.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
id locationValue = [launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey];
if (locationValue)
{
[self initLocationMonitoring]; // this will invoke CLLocationManager
}
return YES;
}
An app that is quitted cant perform any functioning...so i will suggest to recheck those apps ..they must be functioning in the background to check the location of the device...they won't be able to alert if they are quitted.

monitoredRegions empty even though startMonitoringForRegion:desiredAccuracy: is called

I am developing a iPhone app running on iOS5, and am unable to set up geofences when I call the startMonitoringForRegion:desiredAccuracy: method on click of a button.
It works fine in the simulator when I print out the regions in monitoredRegions, but when running on an actual iPhone 4, the monitoredRegions is always empty. Expectedly, the didEnterRegion: and didExitRegion: methods are not called as well.
Another puzzling fact is that on BOTH the simulator and the iPhone 4 device, the CLLocationManagerDelegate method didStartMonitoringForRegion: is never called as well.
Would appreciate some help here, thank you!
EDIT:
this is method that I call on click of a button:
-(void) queueGeofence: (CLLocationCoordinate2D)selectedBranch userCoordinate:(CLLocationCoordinate2D)userCoordinate radius: (CLLocationDegrees)radius {
geofence = [[CLRegion alloc] initCircularRegionWithCenter:selectedBranch radius:radius identifier:#"geofence"];
CLLocationAccuracy acc = kCLLocationAccuracyNearestTenMeters;
[locationManager startMonitoringForRegion:geofence desiredAccuracy:acc];
[CLLocationManager regionMonitoringEnabled];
NSLog([CLLocationManager regionMonitoringEnabled] ? #"regionMonitoringEnabled:Yes" : #"regionMonitoringEnabled:No");
NSLog([CLLocationManager regionMonitoringAvailable] ? #"regionMonitoringAvailable:Yes" : #"regionMonitoringAvailable:No");
NSLog(#"LOCATIONMANAGER monitored regions: %#", [locationManager monitoredRegions]});
}
Region monitoring is both enabled and available, but monitoredRegions is still giving me back nothing.
If you look in CLLocationManager.h, the comments in the header for startMonitoringForRegion:desiredAccuracy: state that
If a region with the same identifier is already being monitored for this application, it
will be removed from monitoring. This is done asynchronously and may not be immediately reflected in monitoredRegions.
Therefore, you shouldn't necessarily expect that [locationManager monitoredRegions] would include your newly added region since it is added asynchronously.
Are you implementing the delegate method for locationManager:monitoringDidFailForRegion:withError:? Maybe that's getting called instead of locationManager:didStartMonitoringForRegion:. Also note that a region with the same identifier as an existing region will get removed, so you might be running into some unexpected problems because you're reusing "geofence" as your identifier.
First of all, you should be sure, that your app has a permission to use LocationManager. Check it when you alloc your manager.
[CLLocationManager authorizationStatus];
I had the same trouble when start app and decline a permission. And after deleting and rebuilding app. I had a flag, that user didn't accept it. Turn it on.
If you are just going by your NSLog, it probably isn't going to work. [locationManager monitoredRegions] returns an NSSet of CLRegions. They won't display to your log that way. Try this:
NSSet *setOfRegions = [locationManager monitoredRegions];
for (CLRegion *region in setOfRegions) {
NSLog (#"region info: %#", region);
}

locationServicesEnabled always return YES

I tested my device (iPod Touch 2G iOS 4.1) if location services are enabled
permitted = [locationManager locationServicesEnabled];
and I always get a YES whether location services are enabled or not. I'm talking about the general button for location services and not the app specific button. On iPad with iOS 3.2.2 everything is working fine.
Remember that [locationManager locationServicesEnabled] is deprecated since iOS 4.0.
Use the Class Method [CLLocationManager locationServicesEnabled] instead.
The App Specific Button can be retrieved by
[CLLocationManager authorizationStatus]
When you use
[CLLocationManager locationServicesEnabled]
then you inspect if locationServices are enabled in whole system. So when you go to Settings -> Location Services and you see that first switch. That method returns state of that state and is not in relation with your app.
If you need to know if your app has access to location services use #Pascalius answer.
When you implement the delegate for location manager, you should be implementing didFailWithError. In there you will get the appropriate error if the user did not allow access to location
Apple Documentation States:
If the user denies your application’s use of the location service, this method reports a kCLErrorDenied error. Upon receiving such an error, you should stop the location service.
Swift 3.1 function returns -> status:Bool and message:String
func isLocationEnabled() -> (status: Bool, message: String) {
if CLLocationManager.locationServicesEnabled() {
switch(CLLocationManager.authorizationStatus()) {
case .restricted, .denied:
return (false,"No access")
case .authorizedAlways, .authorizedWhenInUse:
return(true,"Access")
}
} else {
return(false,"Turn On Location Services to Allow App to Determine Your Location")
}
}
if(![CLLocationManager locationServicesEnabled] || ([CLLocationManager authorizationStatus]!=kCLAuthorizationStatusAuthorizedWhenInUse && [CLLocationManager authorizationStatus]!=kCLAuthorizationStatusAuthorizedAlways))
{
; // app doesn't have access to localization to whatever you want
}
[CLLocationManager locationServicesEnabled] will return NO when the user setting button is switched to OFF, only then I have achieved a NO.

iPhone locationManager:didFailWithError problem when GPS disabled

So, I've followed other related threads, but for some reason I'm still having this error and I'm about ready to tear my hair out. I have implemented locationManager:didFailWithError to check and see if a user selects 'Don't Allow' to use the current location.
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(#"IN ERROR");
if ([error code] == kCLErrorDenied){
[manager stopUpdatingLocation];
}
}
However, the following error always appears when the user selects 'Don't Allow'...it's strange, especially the order that the text 'IN ERROR' appears.
ERROR,Time,293420691.000,Function,"void
CLClientHandleDaemonDataRegistration(__CLClient*,
const
CLDaemonCommToClientRegistration*,
const __CFDictionary*)",server did not
accept client registration 1
2010-04-19 21:44:51.000
testApp[1414:207] IN ERROR
So, it's outputting this error even before it has a chance to get into the didFailWithError function. Does anyone have any ideas of what might be happening? The rest of the locationManager code is as follows:
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
locationManager.distanceFilter = 2;
[locationManager startUpdatingLocation];
Looks like just an informational message from Core Location. It's not crashing your app, the user will not see it and it does still call didFailWithError with the correct error code.
In my tests, the message appears on the iPhone simulator and device (3.1.3) and the iPad simulator but not the iPad device (3.2).
If you're using MapKit as well, this is an error in MapKit. MapKit is registering with Core Location, and then not properly handling the error reported when the user rejects the location update or it fails. It should pass this error on via a delegate method (as it does for geocoding errors), but doesn't.
Unfortunately I can't think of any way to intercept the message from core location, as MapKit maintains an instance of CLLocationManager which it uses to get the location, and that's the one which is reporting the error to its delegate.