How to handle Enable Location Services after a user selects allow? - iphone

Basically when my app launches for the first time the Enable Location Services prompt appears. When the user taps on Allow I would like to start updating user location and zoom into the region.
In my viewDidLoad I start the location manager, but unfortunately the view is loaded before the user has a chance to tap on Allow. Everything works fine on second launch of the application because the user would have allowed location services already
My question is how can I capture the event of tapping on Allow so I can run the code to zoom into a region?
I have tried using -(void)locationManager:didChangeAuthorizationStatus: but it doesn't seem to call this delegate method when the user taps on allow.
Hope this makes sense I am very new to this.

To my knowledge you cannot, but you don't have to capture this event, because you won't be able to zoom to the certain location before you get the coordinates of this location. Your app works fine on the second launch, because it uses cached location data from the first start. So, what you need is to run your zooming code after you received your new valid coordinates.
If you use CLLocationManager, than look at
– locationManager:didUpdateToLocation:fromLocation:
in its delegate. If user denied to use location services, that your delegate will receive
locationManager:didFailWithError:
With corresponding error.
If you use MKMapKit, than in MKMapView delegate implement method
– mapViewWillStartLocatingUser:
to focus on current user position.
to handle denial implement
– mapView:didFailToLocateUserWithError:
Links to corresponding Apple documentation:
CLLocationManager
CLLocationManagerDelegate
MKMapViewDelegate

Here it works just fine. I initiate the location manager, then I set it's delegate and start it. When the popup to allow comes up, the -(void)locationManager:didChangeAuthorizationStatus: is called with CLAuthorizationStatus equals to kCLAuthorizationStatusNotDetermined. If I tap "Dont' Allow", it's called again with CLAuthorizationStatus equals to kCLAuthorizationStatusDenied. When tapping "Allow", it's called with CLAuthorizationStatus equals to kCLAuthorizationStatusAuthorized. Check if your delegate is set correctly.

You can handle it like this :
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
switch([CLLocationManager authorizationStatus])
{
case kCLAuthorizationStatusAuthorized:
NSLog(#"Location services authorised by user");
break;
case kCLAuthorizationStatusDenied:
NSLog(#"Location services denied by user");
break;
case kCLAuthorizationStatusRestricted:
NSLog(#"Parental controls restrict location services");
break;
case kCLAuthorizationStatusNotDetermined:
NSLog(#"Unable to determine, possibly not available");
break;
}
}

Related

How to determine if app shows the "App X would like to use your current location" alert?

Is there a way to figure out programmatically if CoreLocation is displaying that alert?
I'm displaying a welcome screen and want to adapt it's look if the alert shows up.
When you call the instance method of CLLocationManager -startUpdatingLocation, you can schedule a NSTimer with interval of 1 second for example and inside the timer callback call the -authorizationStatus class method of CLLocationManager. If it returns kCLAuthorizationStatusNotDetermined, then the alert is shown and the user should choose either to allow or deny. If he denies then the -locationManager:didFailWithError delegate method is called with error code kCLErrorDenied and you should stop updating location.

Check if user location is visible on map iphone

I want to hide or show a UIButton weather user's current location is visible on map. While testing the code xcode I can see meassage "User location view is NOT visible but should be. Showing...." on console in "didUpdateLocation" method if users location is not visible on map. How can I use this message to generate events in my case to hide or show a UIButton?
Thanks for any help in advance.
If you want to know whether the user location is contained in the currently displayed map region, you can check the userLocationVisible property in the regionDidChangeAnimated delegate method:
- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
someButton.hidden = !mapView.userLocationVisible;
}
If you just want to know whether the user location currently has a value (whether it's visible or not and whether showsUserLocation is on or not), then:
if (mapView.userLocation.location == nil)
NSLog(#"user location not obtained yet");
else
NSLog(#"user location available (may or may not be currently visible)"):
There is property called userLocationVisible.
In Apple Docs
A Boolean value indicating whether the device’s current location is
visible in the map view. (read-only)
if user location is not visible you does not get current lat,long . put the condition if lat ,long == 0. then button hide or show.
it work on only device(gps)

How to make Location Services icon disappear from Status Bar?

My application doesn't need location service to constantly monitor user's location and I really don't want to drain battery, so on startup I get the location, send it to statistics server and call stopUpdatingLocation on my CLLocationManager instance. Icon disappears from status bar! :)
Next, in one of my tabs I have MKMapView in which user can ask for and see (using annotation) his current location. After I switch to another tab with different view I'd like to stop using location services. How to achieve this? I've read SO question What determines the presence of the iPhone Location Services icon in the status bar? and now I'm about to start thinking described use case is a bug in iOS (?).
EDIT: in view with MKMapView I don't use CLLocationManager at all.
In the viewDidDisappear method in the view controller that has the MKMapView, set the mapview's showsUserLocation property to NO.
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
self.mapView.showsUserLocation = NO;
}

iphone how to make sure that application launches only after it gets the user locationn

I am doing the following things to make sure that my application launches only after it gets a location update for the user.
1) My app delegate implements CLLocationManagerDelegate
2) In my app delegate didFinishLaunchingWithOptions method, I am doing
[locationManager startUpdatingLocation]
where locationManager is CLLocationManager instance and then returning YES
3) in my app delegate implemented this method
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
4) Now when didUpdateToLocation methods get called I do
[self.window addSubview:myViewController.view];
[self.window makeKeyAndVisible];
5) I have a splash page also
So this is what I see, the splash page appears for a second or two and then a plain white window appears for a second or so and then I see my myViewController.view
I want to avoid that white plain window to appear, I know it appears because in that time my phone is trying to update user current location, but I would like it to keep displaying the splash screen during that time instead of displaying the white plain window.
Add an image view with the same image you use as your splash screen to the window in MainWindow.xib.
(PS: what a horrible user experience! What will you do if the location manager fails to get a location fix? Or if it takes 30 seconds to get one? Whatever you do, your users will be gone.)
You will have to code to display a copy of the splash screen.
but you also need to consider that the user may decline the Location service permission prompt or not be in a good GPS coverage area or in Airplane mode.
I agree with others here. It can be faked, but this is terrible for the user.
If you application absolutely cannot function without user location I would suggest presenting some screen indicating that the application is locating the user. And if it fails to do so, let the user know this.
Simply making it look like the application take 30 seconds to load is going to turn away many users. So if nothing else please let them know that something is happening back there. (Or better yet, find some way of presenting useful parts of the application while the location is being determined if the app functionality allows it)

Locationservice Indicator stays "on"

I have a created a small app which uses location services on the iPhone. All works well, except the fact, that sometimes, the small arrow in the info-bar stays active even if I explicitly kill the app.
I use the background mode for locationservices, thus the appDelegate methods applicationWillResignActive, applicationDidEnterBackground, applicationWillEnterForeground and applicationDidBecomeActive are implemented but do not touch the location services (well - I need them in background mode).
In that configuration applicationWillTerminate is never called; I implemented all the cleanup cleanup as stopUpdatingLocation in dealloc, as I did not find any other place appropriate for this. But still - the indicator stays on.
Any ideas?
I had the same problem - app leaving the location indicator on in the status bar.
My problem turned out to be that I had originally called the 'startMonitoringSignificantLocationChanges' method of CCLocationManager thinking that would give rough location info that I could up the resolution on when I really needed it.
Unfortunately once an app has called that method once, even if you then delete the app and re-install it it will always re-show the icon in the status bar until the app calls 'stopMonitoringSignificantLocationChanges' on CCLocationManager to unregister itself from the system - complete pain as I have to leave that code in until it has sorted itself out on the several people who were testing my app for me.
So if you get that icon stuck on with your app make sure you've matched any calls to 'startMonitoringSignificantLocationChanges' with a stop call.
if you started your location manager job with
[MyLocationManagerInstance startMonitoringForSignificantLocationChanges];
then you need to stop it with:
[MyLocationManagerInstance stopMonitoringForSignificantLocationChanges];
If you force the termination of the application, applicationWillTerminate isn't called, as, for the OS point of view, it appears as a SIGKILL.
I met a similar problem. The problem only happens on iPhone4, but works perfect on my 3GS. After looking into my code, I found that in my startUpdatingLocation method I used startUpdatingLocation and startMonitoringForRegion services, however, in my stopUpdatingLocation method I just stop updatingLocation service. I fixed this issue by turning off MonitoringForRegion as well.
#pragma mark -
#pragma mark Location methods
- (void)startUpdatingLocation
{
[self.locationManager startUpdatingLocation];
[self.locationManager startMonitoringForRegion:desRegion desiredAccuracy:50.0f];
}
- (void)stopUpdatingLocation
{
[self.locationManager stopUpdatingLocation];
// !!!: fix location service indicator stuck issue
[self.locationManager stopMonitoringForRegion:desRegion];
}
Ok, problem solved. The indicator will stay on until a new location is found. Then if everything else is correct, the indicator turns off.