CLLocation won't start updating location - ios

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];

Related

Do not show alert each time when startUpdatelocation

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");
}

How to get location on each 200 meters in terminated state in ios

i am trying to get user's location in app's terminated state. i am doing this by startMonitoringSignificantLocationChanges but it's giving location after 3km or after 5 min. so can't create a route properly. please guide me how to do this.
if (_anotherLocationManager)
[_anotherLocationManager stopMonitoringSignificantLocationChanges];
self.anotherLocationManager = [[CLLocationManager alloc]init];
_anotherLocationManager.delegate = self;
_anotherLocationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
_anotherLocationManager.activityType = CLActivityTypeOtherNavigation;
if(IS_OS_8_OR_LATER) {
[_anotherLocationManager requestAlwaysAuthorization];
}
[_anotherLocationManager startMonitoringSignificantLocationChanges];
I solved my query myself...
Create a locationManager object and alloc it like this
self.locationManager = [[CLLocationManager alloc]init]; // initializing locationManager
_locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation; // setting the accuracy
[self.locationManager requestAlwaysAuthorization];
if([self.locationManager respondsToSelector:#selector(allowsBackgroundLocationUpdates)]) {
[self.locationManager setAllowsBackgroundLocationUpdates: YES];
}
self.locationManager.distanceFilter = 20.0;
[self.locationManager startMonitoringSignificantLocationChanges];
self.locationManager.activityType=CLActivityTypeAutomotiveNavigation;
[self.locationManager startUpdatingLocation];
self.locationManager.pausesLocationUpdatesAutomatically = YES;
self.locationManager.delegate = self;
Now set location manager delegate method.
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
{
if (newLocation.speed>7){
// here you got location, i settled speed 7 for my convenience.
}
if (newLocation.horizontalAccuracy <= self.locationManager.desiredAccuracy) {
//Desired location Found
[self.locationManager stopUpdatingLocation ];
}
}
You must have to write this stopUpdatingLocation, else your battery consumption will increase so high.
Use the Geofencing to achieve the same.
Create a Geofence of 200mtr radius.
By default, notifyOnExit would be true
Implement the delegate didExitRegion of LocationManager
For termination state, the app would be lunched with UIApplication.LaunchOptionsKey.location in didFinishLaunchingWithOptions.
Create an instance of Location Manager object on location launch key, you obtain the region at which the location exited and keep creating the 200mtr fence on every exit.
You're not going to get 200 meter granularity or continuous tracking with significant location monitoring.
Have you seen these notes in the docs:
The significant-change location service delivers updates only when
there has been a significant change in the device’s location, such as
500 meters or more.
If GPS-level accuracy isn’t critical for your app and you don’t need
continuous tracking, you can use the significant-change location
service.

Always On Location Not Being Requested

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

CLLocationmanager updateLocations delegate method not getting called in iOS 8

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.

CLLocation didupdatetolocation not called

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.

Resources