5

I am using CLLocationManager class. I have a simple class method for capturing the location

+(void)captureLocation{
    mLocationManager = [[CLLocationManager alloc]init];
    mLocationManager.delegate = (id<CLLocationManagerDelegate>)self;
    mLocationManager.desiredAccuracy = kCLLocationAccuracyBest;
    [mLocationManager startUpdatingLocation];
}

and i have the delegate methods of CLLocationManager also

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation   *)newLocation fromLocation:(CLLocation *)oldLocation
{
}

now i am trying to call this method in my viewDidLoad as

- (void)viewDidLoad
{
    [super viewDidLoad];
    [myclass captureLocation];
}

the method is getting called but the delegate methods are not getting called.

I have other class method also and from there if I try to call the method again the captureLocation method is getting called but the delegate methods are not called. Here is the other class method

+(void)initialize{
    [self captureLocation];
}

please help me to find out why delegate methods are not getting called as I am new to this field. Thanks in advance.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
Newbee
  • 265
  • 3
  • 9
  • 22
  • Have you set the delegate of your Object? – NinjaLikesCheez Nov 19 '13 at 13:00
  • check this : http://stackoverflow.com/questions/19603830/location-manager-giving-null-coordinates/19603959#19603959 – Dhaval Bhadania Nov 19 '13 at 13:02
  • Unrelated to your problem at hand, given that you used the `ios7` tag, it's worth noting that if targeting only iOS 6 and later, then it might be prudent to use `locationManager:didUpdateLocations:` rather than `locationManager:didUpdateToLocation:fromLocation:`. The latter method was deprecated in iOS 6 and might eventually be removed entirely. Your code will be more future-proof if you use the `didUpdateLocations` rendition. – Rob Nov 19 '13 at 13:48
  • 1
    Possible duplicate of [Why the CLLocationManager delegate is not getting called in iPhone SDK 4.0?](http://stackoverflow.com/questions/3058927/why-the-cllocationmanager-delegate-is-not-getting-called-in-iphone-sdk-4-0) – Max MacLeod Nov 12 '15 at 10:04

5 Answers5

12

Also know that CoreLocation permissions have changed with iOS 8. If you don't request the new permissions authorizations, CoreLocation doesn't do anything. It fails quietly because the delegate methods are never called.

I realize this question was asked in 2013, but if you are having a similar problem with the delegate methods not getting called, this article is extremely helpful:

http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/

While the article is very detailed and long, the actual code fix can be as minor as this:

if ([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
    [locationManager requestWhenInUseAuthorization];
}

And you have to add a value to info.plist, which is the message to display in the permissions alert. See screen grab.

Screen grab of new entry in info.plist

Key: NSLocationWhenInUseUsageDescription

Value: Location is required to find out where you are (You can change that to whatever you want)

Hugh
  • 443
  • 4
  • 11
  • 2
    Thank you very much for giving the link. I don't know why people won't give upvote for this answer, due to no vote I was ignoring this answer..... Thanx again – sandy May 26 '15 at 12:13
  • 1
    Thanks. Saved my time – Prabha Nov 27 '15 at 09:47
5

You are setting the delegate of the CLLocationManager inside a class method (i.e. one prefixed by + rather than -). So, when you reference self within that class method, that's the class, not an instance of the class. So, you are trying to set the delegate to the class rather than an instance of the class.

That won't work. The delegate methods are instance methods, not class methods. (This is presumably why you had to use the CLLocationManagerDelegate cast when assigning the delegate.)

You must actually instantiate whichever class you've implemented the CLLocationManagerDelegate methods. If you don't want to tie that instance to a particular view controller, you could use a singleton pattern. Regardless, you can set the location manager's delegate to point to that instance of that class.


For example, if you wanted it to be a singleton:

//  MyClass.h

#import <Foundation/Foundation.h>

@interface MyClass : NSObject

+ (instancetype)sharedManager;
- (void)startCapture;
- (void)stopCapture;

@end

and

//  MyClass.m

#import "MyClass.h"
#import <CoreLocation/CoreLocation.h>

@interface MyClass () <CLLocationManagerDelegate>

@property (nonatomic, strong) CLLocationManager *locationManager;

@end

@implementation MyClass

+ (instancetype)sharedManager
{
    static id sharedMyManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedMyManager = [[self alloc] init];
    });
    return sharedMyManager;
}

- (void)startCapture
{
    self.locationManager = [[CLLocationManager alloc] init];
    self.locationManager.delegate = self;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    [self.locationManager startUpdatingLocation];
}

- (void)stopCapture
{
    [self.locationManager stopUpdatingLocation];
    self.locationManager = nil;
}

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    // ...
}

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    // ...
}

@end

And then,

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[MyClass sharedInstance] startCapture];
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • i dont want my class method to change to instance method. is it possible to call the delegate methods from a class method? – Newbee Nov 21 '13 at 08:54
  • @Newbee No, the delegate methods are instance methods, and thus must be called on an instance of the object. You could have your class method instantiate a singleton or do it like I have in my revised answer which makes it a tad more obvious that you're dealing with a singleton. – Rob Nov 21 '13 at 13:28
0

Calling self in a + method set your delegate to nil as it means ClassName as in [[ClassName alloc] init].

you need to:

mLocationManager.delegate = mLocationManager

instead of

mLocationManager.delegate (id<CLLocationManagerDelegate>)self;
Nicolas Manzini
  • 8,379
  • 6
  • 63
  • 81
0

in ios6 locationManager:didUpdateToLocation:fromLocation: is deprecated so you need to add another method in your code ...

-(void)locationManager:(CLLocationManager *)manager
   didUpdateToLocation:(CLLocation *)newLocation
          fromLocation:(CLLocation *)oldLocation
{

      // this method get called in ios7 . 
}
Shaik Riyaz
  • 11,204
  • 7
  • 53
  • 70
0

In iOS -8 need to do some changes :

Please have a look into this :Get current location in iOS-7 and iOS-8

Community
  • 1
  • 1
Alok
  • 24,880
  • 6
  • 40
  • 67