Neelesh
Neelesh

Reputation: 3693

CLLocationManager startUpdatingLocation using a UIButton

This is the first time I am using CLLocationManager. I am not sure if i am doing the right thing. Correct me if i am wrong.

I initialize the locationManager in my viewDidLoad Method and tell the locationManager to startUpdatingLocation in the same method.

When the delegate receives

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

    [locationManager stopUpdatingLocation];
    //do stuff with the coordinates
}

to avoid repeated calls to this delegate method.

I have a UIButton where users can click to update the location

//called by user action
-(IBAction)updateLocation{
    //start updating delegate
    locationManager.delegate=self;
    [locationManager startUpdatingLocation];    
}

However when the location changes and when I click the UIbutton, the location coordinates donot change at all. :(

What am i doing wrong? Is this the right of doing or should i not stop the locationManager at all ?

Help would be appreciated.

Upvotes: 1

Views: 17531

Answers (2)

GarlicFries
GarlicFries

Reputation: 8323

CLLocationManager caches your last location and returns it as soon as you call -startUpdatingLocation. So, you are starting updates, receiving the old location, and then stopping updates.

This isn't how -startUpdatingLocation/-stopUpdatingLocation are meant to be used. As I asked above, what's wrong with calling the delegate method multiple times? If you only want to get the location when the user taps a button, leave the CLLocationManager updating, and just check CLLocationManger's location property when the user taps your button.

If the reason you're trying to avoid multiple calls to the delegate method is because you're worried about power consumption, etc., adjust the desiredAccuracy property of the CLLocationManager with something like: locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters.

All told, it might look something like this...

.h file:

@interface YourController : NSObject <CLLocationManagerDelegate>

@property (nonatomic, retain) CLLocationManager *locationMgr;
@property (nonatomic, retain) CLLocation *lastLocation;

- (IBAction)getNewLocation:(id)sender;

@end

.m file:

@interface YourController

@synthesize locationMgr = _locationMgr;
@synthesize lastLocation = _lastLocation;

- (id)init
{
    if (self = [super init]) {
        self.locationMgr = [[CLLocationManager alloc] init];
        self.locationMgr.desiredAccuracy = kCLLocationAccuracyBest;
        self.locationMgr.delegate = self;
    }
    return self;
}

- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
           fromLocation:(CLLocation *)oldLocation
{
    if (!self.lastLocation) {
        self.lastLocation = newLocation;        
    }

    if (newLocation.coordinate.latitude != self.lastLocation.coordinate.latitude &&
        newLocation.coordinate.longitude != self.lastLocation.coordinate.longitude) {        
        self.lastLocation = newLocation;
        NSLog(@"New location: %f, %f",
              self.lastLocation.coordinate.latitude,
              self.lastLocation.coordinate.longitude);
        [self.locationMgr stopUpdatingLocation];
    }
}

- (IBAction)getNewLocation:(id)sender
{
    [self.locationMgr startUpdatingLocation];
    NSLog(@"Old location: %f, %f", 
          self.lastLocation.coordinate.latitude, 
          self.lastLocation.coordinate.longitude);
}

- (void)dealloc
{
    [self.locationMgr release];
    self.locationMgr = nil;
    [self.lastLocation release];
    self.lastLocation = nil;
    [super dealloc];
}

@end

Upvotes: 10

Srikar Appalaraju
Srikar Appalaraju

Reputation: 73678

Am assuming you have included #import <CoreLocation/CoreLocation.h> framework to being with. This is the way you start getting location updates.

CLLocationManager *locationMgr = [[CLLocationManager alloc] init];
locationMgr.desiredAccuracy = kCLLocationAccuracyBest;
locationMgr.delegate = self;

[locationMgr startUpdatingLocation];

You are correct here. After this you start getting location updates, here in this delegate-

-(void)locationManager:(CLLocationManager *)manager
   didUpdateToLocation:(CLLocation *)newLocation
   fromLocation:(CLLocation *)oldLocation
{
    // Handle location updates
} 

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

Upvotes: 0

Related Questions