How to update location only when button is pressed
How can I make my application update location only when a button is pressed?
I have a button named "REFRESH". Everytime this button is pressed, I want to show my user their location. For example, 51 Bourke Street, Victoria
.
However, I do not want to update my location regularly. I want to update its location only when the button is pressed, to save battery power.
What do you think? Am I doing it correctly?
I have these classes:
- VoteViewController.h and VoteViewController.m
- CoreLocationController.h and CoreLocationController.m
This is what I have:
VoteViewController.h
class
@interface VoteViewController : UIViewController <CoreLocationControllerDelegate>
{
CoreLocationController *coreController;
}
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
- (void)geoReverseAddress:(MKPlacemark *)placeMark;
- (IBAction)refreshButtonPressed;
VoteViewController.m
class
- (void)viewDidLoad
{
[super viewDidLoad];
coreCont开发者_运维问答roller = [[CoreLocationController alloc] init];
coreController.delegate = self;
}
- (IBAction)refreshButtonPressed
{
NSLog(@"Refresh Button pressed");
label.text = [NSString stringWithString:@""];
[coreController.locationManager startUpdatingLocation];
}
- (void)locationUpdate:(CLLocation *)location
{
comments.text = [location description];
[coreController.locationManager stopUpdatingLocation];
}
- (void)locationError:(NSError *)error
{
comments.text = [error description];
[coreController.locationManager stopUpdatingLocation];
}
- (void)geoReverseAddress:(MKPlacemark *)placeMark
{
label.text = [NSString stringWithFormat:@"%@ %@, %@", [placeMark subThoroughfare],
[placeMark thoroughfare], [placeMark locality]];
}
CoreLocationController.h
class
@protocol CoreLocationControllerDelegate <NSObject>
@required
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
- (void)geoReverseAddress:(MKPlacemark *)placeMark;
@end
@interface CoreLocationController : NSObject <CLLocationManagerDelegate, MKReverseGeocoderDelegate>
{
CLLocationManager *locationManager;
id delegate;
MKReverseGeocoder *reverse;
}
@property(nonatomic, retain) CLLocationManager *locationManager;
@property(nonatomic, retain) id delegate;
@end
CoreLocationController.m
class
-(id) init
{
self = [super init];
if (self != nil)
{
self.locationManager = [[[CLLocationManager alloc] init] autorelease];
self.locationManager.delegate = self;
self.locationManager.distanceFilter = kCLHeadingFilterNone;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(@"Update location");
[self.delegate locationUpdate:newLocation];
reverse = [[MKReverseGeocoder alloc] initWithCoordinate:[newLocation coordinate]];
reverse.delegate = self;
[reverse start];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
[self.delegate locationError:error];
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFailWithError:(NSError *)error
{
[self.delegate locationError:error];
[reverse cancel];
[reverse release];
}
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark
{
[self.delegate geoReverseAddress:placemark];
[reverse cancel];
[reverse release];
}
When you first fire up CLLocationManager, you're very likely to get one stale location from the last time it ran. Once that's out of the way, you're going to start getting very inaccurate locations while the device uses WiFi sniffing and cell triangulation, while the GPS looks for a fix.
So in your didUpdateToLocation method, you probably want to throw away the first hit, and then test the .horizontalAccuracy value of your newLocation object for a low enough value to trust.
Apart from that, I don't see anything bad about what you've sent here. I'm not sure I'd go to the trouble of wrapping the location fetching work in its own class, I'd probably just do that out in my viewController. But that's a style choice. If you're reusing this functionality elsewhere, what you've got here is obviously the way to go.
精彩评论