How can I observe and call a method when the location services options change? For example, my app runs location services in the background, i.e. the option in Settings is set to always. What if the user changes the option while my app is still running, how can observe changes and make changes in my app accordingly?
Implement the CLLocationManagerDelegate method
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
From the docs:
"This method is called whenever the application’s ability to use location services changes. Changes can occur because the user allowed or denied the use of location services for your application or for the system as a whole."
Related
I do have a situation where I need to get current location of iPhone 5 running iOS8. When the location services is off, the default location service alert open up. This alert has 'Cancel' and 'Settings' button. Please find below the screenshot of the alert.
I need to handle the situation when user pressed cancel on the alert. I can handle it when I override the alert. But that alert isn't working for me, as settings of that custom alert takes me to the app level location settings and not device level location settings.
Set the delegate for your CLLocationManager and implement the delegate's method
- locationManager:didChangeAuthorizationStatus:
This method is called whenever the application’s ability to use location services changes. Changes can occur because the user allowed or denied the use of location services for your application or for the system as a whole.
If the authorization status is already known when you call the requestWhenInUseAuthorization or requestAlwaysAuthorization method, the location manager does not report the current authorization status to this method. The location manager only reports changes to the authorization status. For example, it calls this method when the status changes from kCLAuthorizationStatusNotDetermined to kCLAuthorizationStatusAuthorizedWhenInUse.
Link to Apple doc
In my app, I am using the Boundary-Crossing Events for a Geographical Region to determine if a user has visited a location. This is working as expected when users have installed the app prior to visiting the location, however some users will be installing the app while they are at the event, and therefore are already within the location when the event is installed and so iOS does not treat this as a boundary crossing.
Is there a way to force iOS to trigger the locationManager:didEnterRegion method if the startMonitoringForRegion method is called while the device is currently within the region to monitor?
In iOS7, you can use requestStateForRegion: method of the CLLocationManager class to check whether the user is already inside a fence.
You need to implement below delegate method to receive the event.
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region {
}
Thanks to this article for the answer (as well as a solution for iOS version < 7: http://hayageek.com/ios-geofencing-api/
I want to attach a listener in IOS which is invoked whenever GPS is turned ON or OFF from settings. Listener should be invoked no matter my application is running, in background or has been stopped. I have this functionality that i need to keep GPS settings of a user who has installed app, on server side, so whenever GPS is changed i must notify the server.
I guess there isn't any listener,
You can Use Delegate method of CLLocationManager.
Use this delegate method for getting location - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
Form this [locations lastObject] you can latest location send location to server.
You can not get location when app is stopped.
As of now, there is no such notification exists.
However you can create and start a timer (NSTimer) that will regularly poll whether GPS is enabled or not, using 'CLLocationManager locationServicesEnabled' method.
Within your class, you can have a bool iVar that will be set / reset based on return value. Whenever its value is altered, you can notify server about service start / stoppage.
Is there a way to delay code from running until the user has answered the current location prompt? My app fetches annotations and puts them on the map. When the app launches for the first time and the user allows current location it fails to fetch any annotations because the code already ran without receiving a current location. Thanks in advance.
You can implement the following CLLocationManagerDelegate method:
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
and only show your annotations after that method is called. It will be called when the user accepts or rejects the current location prompt.
I might be confusing how region monitoring works, but this is what i have so far:
I am registering a region to monitor through my location manager, which is implemented on a singleton class, this singleton is also set as the delegate of the location manager so the implemented method is being called.
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
This works totally as expected, if the app is active or suspended the method is being called. It also makes total sense because the class has been already loaded and when the region enter event occurs iOS sends this even to my app which calls the location manager who registered (probably has a reference to it) and in turn it calls whatever delegate was also registered along it (since the class is there ready and loaded).
The issue is, what happens when the app has been killed? Is it first launched into the background? How does iOS know what delegate method to call, and if it has already been loaded?
When your app has been killed and gets started for a location update there can't be a location manager delegate yet and as such there are no notifications delivered to that delegate. The system can't know which of your classes should be used as a location manager delegate or how to instantiate it.
Instead your application:didFinishLaunchingWithOptions: gets called as usual, but the UIApplicationLaunchOptionsLocationKey is set in the options dictionary. That tells your app that you need to instantiate a location manager and set it's delegate. Only after you did this the delegate gets called with the region updates.