I am working on location app where I need to get the location. When I come on the particular ViewController & location is off it gives alert showing that switch on the location which is fine.But the problem is once I say cancel & next time call [locationManager startUpdatingLocation]; it will not show me alert to switch on location.
- (void)getCurrentLocation {
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
locationManager.distanceFilter = kCLDistanceFilterNone;
if ([locationManager respondsToSelector:#selector(requestAlwaysAuthorization)]) {
[locationManager requestAlwaysAuthorization];
}
[locationManager startUpdatingLocation];
}
Note - I have done changes in plist to
NSLocationAlwaysUsageDescription set to The XYZ app would like to use
your current location
Sadly this is by design. Its so an app developer can't harass the user with endless requests.
What you have to do is check the [CLLocationManager authorizationStatus] and if its kCLAuthorizationStatusDenied then display a message that the user needs to go into their settings app and enable locations for your app.
You should handle the other authorized states as well. See the list in the CLLocationManager Documentation - CLAuthorizationStatus
Check the status before startUpdatingLocation. i.e.
if([CLLocationManager locationServicesEnabled])
{
if([CLLocationManager authorizationStatus]==kCLAuthorizationStatusDenied){
NSLog(#"Add your alert here");
}
else
{
[locationManager startUpdatingLocation];
}
}
else
{
NSLog(#"Add your alert here");
}
Related
I have an app that uses background location updates, it needs to constantly track the devices position regardless if the app is in the foreground or background. I have the background tracking setup in the app delegate.
In the front end I have a single UIViewController with a working mapkit view all the CCLocationManager code triggers without error but didUpdateUserLocation is never fired within the custom UIViewController class.
Background location tracking is working with absolutely no problems.
Here is the code i'm using in viewDidLoad
[self.mapView setShowsUserLocation:YES];
[self.mapView setShowsPointsOfInterest:YES];
self.locationManager = [[CLLocationManager alloc] init];
[self.locationManager requestWhenInUseAuthorization];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.distanceFilter = kCLDistanceFilterNone;
[self.locationManager setDelegate:self];
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
NSString *error;
if (![CLLocationManager locationServicesEnabled]) {error = #"Error message";}
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusRestricted || status == kCLAuthorizationStatusDenied) {error = #"Error message";}
if (error) {NSLog(error);}
else
{
status = [CLLocationManager authorizationStatus];
self.locationManager.pausesLocationUpdatesAutomatically = NO;
self.locationManager.activityType = CLActivityTypeAutomotiveNavigation;
[self.locationManager stopMonitoringSignificantLocationChanges];
[self.locationManager startUpdatingLocation];
}
Any help would be appreciated
Thanks
You need to check below details:
Testing this on simulator?? didUpdateLocations must be tested on real device.
Make sure that you specified the NSLocationAlwaysUsageDescription string or else the app won't present the authorization message, and you won't be authorized.
Have you implemented locationManager:didFailWithError:? did you got any error?
Have you implemented locationManager:didChangeAuthorizationStatus:? Are you getting this called with a successful authorization status?
I worked out the problem finally.
Turns out even if you're using the location stuff in Schema and Xcode you still need to set it in the Simulator via Debug > Location
Hopefully this helps someone else.
and now, with iOS 9, the following needs to be included for any update;
if ([ locationManager respondsToSelector:#selector(requestWhenInUseAuthorization )])
{
locationManager.allowsBackgroundLocationUpdates = YES;
}
Else background updates will be impaired.
I'm asking this because I'm a bit confused. I did set NSLocationAlwaysUsageDescription in my Info.plist and this is the code I'm running:
CLLocationManager *locMan = [[CLLocationManager alloc] init];
locMan.delegate = self;
if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorizedAlways)
{
[locMan requestAlwaysAuthorization];
}
[locMan startUpdatingLocation];
I set a breakpoint and verified that this does indeed get called, but I am not alerted in the app. I check in my privacy settings and saw the app had an entry with the two options: None and Always, with neither checked. I tried to uninstall, clean, and reinstall, but still is not working. Any ideas?
EDIT:
I moved the above block from viewDidLoad into viewDidAppear: and now the alert comes up and disappears half a second later
I solved my issue. It's a retain issue. I was declaring my CLLocationManager locally, so when it reached the end of my method, it would didn't exist anymore, which explains why it couldn't ask for permission. I promoted it to be a property and now all works well
You need to add this line at the end of your code
[self.locationManager startUpdatingLocation];
What about if you try this:
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
if ([locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[locationManager requestWhenInUseAuthorization];
}
[locationManager startUpdatingLocation];
Sorry, missread your post. Maybe try this:
CLAuthorizationStatus status = [CLLocationManager authorizationStatus];
if (status == kCLAuthorizationStatusAuthorizedWhenInUse || status == kCLAuthorizationStatusDenied) {
// Show alert or something
}
else if (status == kCLAuthorizationStatusNotDetermined) {
[self.locationManager requestAlwaysAuthorization];
}
More can be read here: Core Location Manager Changes in iOS 8
I am having a lot of trouble after updating to iOS 8. The following code worked before I updated to iOS and Xcode 6. Code is written inside viewDidLoad:
self.locationManager.delegate = self;
[self.locationManager requestWhenInUseAuthorization];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
In my .h file, I have locationManager as a property, also declaring CLLocationManagerDelegate:
#property CLLocationManager *locationManager;
I've set a breakpoint inside
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
but the code never ran.
What step am I missing???
EDIT: do note that the prompt asking the user to allow location services never appeared. I suspect that this is the issue but I did request the service right after I declared the delegate to self.
Also added
<key>NSLocationWhenInUseUsageDescription</key>
<string>Your message goes here</string>
But still does not work for me
if you start location before user agree to use location server
ios8 or later change to
- (xx)xxxx
{
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedAlways) {
[self.locationManager startUpdatingLocation];
}else{
[self.locationManager requestWhenInUseAuthorization];
}
}
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
if([CLLocationManager authorizationStatus] != kCLAuthorizationStatusNotDetermined){
[self.locationManager startUpdatingLocation];
}
}
You need to add NSLocationWhenInUseUsageDescription key to your info.plist. (From my testing, it can be an empty string, but the key must exist. Not sure if Apple fails review for empty string, though.)
You need to use requestAlwaysAuthorization (for background location) or requestWhenInUseAuthorization (location only when foreground) call on CLLocationManager is needed before starting location updates.
There also needs to be NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription key in Info.plist with a message to be displayed in the prompt.
More information in this post: Location Services not working in iOS 8
So after all the "iOS 8" issues, I realized my problem was that I didn't allocate and init my locationManager
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
[self.locationManager requestWhenInUseAuthorization];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedAlways) {
[self.locationManager startUpdatingLocation];
}else{
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
}
[self.locationManager startUpdatingLocation];
Am using CLLocationManager to get current location . Specifically in iOS 8 , it's delegate methods are not getting fired .
I have set allow in location services please refer screen shot below
Please find my code below:
self.myLocationManager = [[CLLocationManager alloc]init];
[self.myLocationManager setDelegate:self];
self.myLocationManager.distanceFilter = kCLDistanceFilterNone;
self.myLocationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.myLocationManager startUpdatingLocation];
and i tried using method of iOS 8 . And set a property NSLocationAlwaysUsageDescription in plist but still am not able to get location
self.myLocationManager requestAlwaysAuthorization];
Step 1:
Add the below code:
SEL requestSelector = NSSelectorFromString(#"requestAlwaysAuthorization");
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined &&
[locationManager respondsToSelector:requestSelector]) {
[locationManager performSelector:requestSelector withObject:NULL];
} else {
[locationManager startUpdatingLocation];
}
Step 2:
Add NSLocationAlwaysUsageDescription to info.plist
It doesn't look like you've set a value for NSLocationAlwaysUsageDescription.
Spent few days trying to solve this but unable to find any solutions that works. I have checked all the post on stackoverflow and tried all their solutions and nothing seems to be working for. I have also tried the apple test project for CLLocation which works fine for me. I used bits and pieces from the apple test project
https://developer.apple.com/library/ios/samplecode/LocateMe/Listings/README_md.html
But my code is not working at all. The DidupdateToLocation never gets called.
Here is my code (in viewDidLoad)
_locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
// This is the most important property to set for the manager. It ultimately determines how the manager will
// attempt to acquire location and thus, the amount of power that will be consumed.
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
// Once configured, the location manager must be "started"
//
// for iOS 8, specific user level permission is required,
// "when-in-use" authorization grants access to the user's location
//
// important: be sure to include NSLocationWhenInUseUsageDescription along with its
// explanation string in your Info.plist or startUpdatingLocation will not work.
//
if ([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]) {
[self.locationManager requestWhenInUseAuthorization];
}
[self.locationManager startUpdatingLocation];
[self performSelector:#selector(stopUpdatingLocationWithMessage:)
withObject:#"Timed Out"
afterDelay:30];
I have checked to make sure locationServicesEnabled is enabled.
I have added NSLoationWhenInUseUsageDescription property to the info.plist file. Is there any other property I need to add or enable any services??
I cannot for the love of god figure out what i have done wrong. Can some one please help me with this.
You have to call the startUpdatingLocation after you received the didChangeAuthorizationStatus callback on iOS8.
//iOS 8 API change
if([self.locationManager respondsToSelector:#selector(requestWhenInUseAuthorization)]){
[self.locationManager requestWhenInUseAuthorization];
}else{
[self.locationManager startUpdatingLocation];
}
implement this delegate method:
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
switch (status) {
case kCLAuthorizationStatusNotDetermined:
case kCLAuthorizationStatusRestricted:
case kCLAuthorizationStatusDenied:
{
// do some error handling
}
break;
default:{
[self.locationManager startUpdatingLocation];
}
break;
}
}
First, don't forget, with IOS 8 you need to do [locationManager requestWhenInUseAuthorization] plus [locationManager requestAlwaysAuthorization];
_locationManager = [CLLocationManager new];
if(SYSTEM_IS_OS_8_OR_LATER) {
[_locationManager requestWhenInUseAuthorization];
[_locationManager requestAlwaysAuthorization];
}
_locationManager.delegate = self;
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
//and the problem with your code : don't forget to start
_locationManager startUpdatingLocation];
and in your didUpdateLocations
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
_currentLocation = [locations objectAtIndex:0];
//do your stuff with the location
}
Silly me. I added the keywords to the wrong plist file. I have got it working now. Thanks for your help guys.
I just spend an entire morning on this [in honestly I am relative new OOC], anyway the problem..
didUpdateLocation compiles and is never called
didUpdateLocations compiles and does work!!
Not the answer in this case it would seem, but it is in the question, an easy mistake to make. Using IOS 8.1.3 & Xcode 6.1.1
Simply add three properties in Info.plist.
To get the current location, if it is not calling didUpdateToLocation method
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
privacy - location usage description of type String.