views:

464

answers:

3

While my app is displaying a UIActionSheet, I send startUpdatingLocation to the CLLocationManager. This results in a Location Warning, if the user has not yet agreed to letting my app use her location.

Now, the problem is, that the UIAlertView that the Location Manager displays pops up behind my UIActionSheet, and thus the user can not interact with it (thus the location updates never come in, thus the action sheet is never dismissed...).

Is there a way to make the Location Manager dialog appear on the very top (or my action sheet behind it)?

If it's relevant: there is a UITabBar and I use showFromTabBar to display the action sheet.

A: 

You should wait until the user confirms that he/she wants to use the GPS and gives permission to use his/her current position before starting updating the location. What if the user is not willing to use the GPS?

unforgiven
that is not how location manager works. i can't actually get any location until the user confirms, but i have to start trying in order to get the system to display the dialog
hop
You are absolutely right. I have written my GPS code some time ago (for SDK 2.x, then updated for 3.x) and I forgot this.
unforgiven
A: 

Ok,

you can try this. Before starting location updates, use the following property of CLLocationManager

@property(readonly, NS_NONATOMIC_IPHONEONLY) BOOL locationServicesEnabled

If the property value is YES then you can safely start updating the location, and the iPhone OS should not present the UIAlertView asking to enable the location services.

If the value is NO, then dismiss your UIActionSheet before starting updating the location. Hope this helps, otherwise simply disregard the answer ;-)

unforgiven
wrong again. locationServicesEnabled is only false when the user has disabled location services in the preferences, not when they are enabled, but the app has not yet been cleared for receiving updates.i appreciate your help, though!
hop
A: 

Let's go for the third round.

The iPhone OS should ask you whether to use your position or not ONLY if there is not an already cached location, i.e. it should ask only the first time. Now, I may be wrong for the third time in a row, but you can try this property of CLLocationManager:

The most recently retrieved user location. (read-only)

@property(readonly, NS_NONATOMIC_IPHONEONLY) CLLocation *location

If the property is nil, then there is no cached location and the OS will ask the user using the UIAlertView. Otherwise no confirmation panel should appear.

If the property value is not nil then you should safely start updating the location, and the iPhone OS should not present the UIAlertView

If the property is nil, then dismiss your UIActionSheet before starting updating the location. I wait the third down vote, if I deserve it ;-)

unforgiven
no downvote yet ;) it strikes me as an unelegant solution for several reasons (if it works at all): because of the asynchronous nature of interacting with location manager and because it would use undocumented features of the state of the location property. to be honest, the real problem is that i shouldn't use a modal view while updating the location in the background, but the customer is king...
hop
A tradeoff may be acceptable if you don't want to change your UI. I have just tried this in one of my apps. To clear the cached information I need to switch off the device (the property is read-only). However, in all of my tests, the app is NEVER asking me the permission to use my position. This applies to both runs in which no cached location is available and runs in which instead a location is already in cache. Therefore I am not able to confirm if this works. Any idea why I am never being asked for permission?
unforgiven
It works like a charm. I have solved the mistery as follows. Removing the application from the device, switching it off and on, and installing again the application causes the confirmation panel to appear and I have verified that the location property is always nil in this case. Once this happens, the app never asks again for confirmation if the location property is not nil. I know this is clearly a tradeoff, but it may be the only option you have, unless you decide to change your UI.
unforgiven
By the way, this is not undocumented: the CLLocationManager class reference says regarding the property: "The value of this property is nil if no location data has ever been retrieved." And the overview says: "The location service returns an initial location as quickly as possible, returning cached information when available."
unforgiven
it's the "ever" that makes me cautious... ever since the app started? ever since the phone booted? ever since the gps unit was turned on? the behaviour could change with every os update.
hop
btw, you can force the confirmation panel to reappear by resetting "location warnings" in general preferences -> reset. no need to uninstall the app or reboot the phone.
hop
Sure, the behaviour may change with every OS update, but this is true of every method/property. Apple can decide at will to change everything: the important thing is that the current behaviour is actually documented and supported by Apple for SDK 3.1. You are not using an undocumented method/property. Thank you very much for suggesting how to reset the location warnings, this is quite handy. I never noticed that, since I have never had a need to reset my devices before.
unforgiven