I've heard time and time again that there is always a better pattern than the singleton, but I can't understand how else my application could access the device location without waiting for the GPS to return data (I'm assuming that the location system is only running when explicitly called for, correct me if wrong).
So is there a better pattern for accessing CLLocation data from multiple (unrelated) controllers? Or can I expect the device location to be updating in the background even if I am not accessing it through a CLLocationManager?
Declare a single class . Like the following .
MyLocation.h
@protocol MyCLControllerDelegate <NSObject>
- (void)locationUpdate:(CLLocation *)location;
- (void)locationError:(NSError *)error;
@end
@interface MyLocation : NSObject <CLLocationManagerDelegate> {
CLLocationManager *locationManager;
id delegate;
}
@property (nonatomic, strong) CLLocationManager *locationManager;
@property (nonatomic, strong) id <MyCLControllerDelegate> delegate;
MyLocation.m
#import "MyLocation.h"
@implementation MyLocation
@synthesize locationManager;
@synthesize delegate;
- (id) init {
self = [super init];
if (self != nil) {
if([CLLocationManager locationServicesEnabled]) {
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied || [CLLocationManager authorizationStatus] == kCLAuthorizationStatusRestricted )
{
[self showAlertWithTitle:@"Warning" andWithMessage:@"Determining your current location cannot be performed at this time because location services are enabled but restricted" forTargetView:self];
NSlog(@"Determining your current location cannot be performed at this time because location services are enabled but restricted");
}
else
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self; // send loc updates to myself
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationManager setDistanceFilter:kThresholdDistance];
[self.locationManager startUpdatingLocation];
NSLog(@"Location sharing set ON!");
}
} else {
[MobileYakHelper showAlertWithTitle:@"Error" andWithMessage:@"Determining your current location cannot be performed at this time because location services are not enabled." forTargetView:self];
NSLog(@"Location sharing set OFF!");
}
}
return self;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSDictionary *dictValue = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithDouble:newLocation.coordinate.latitude], @"latitude",
[NSNumber numberWithDouble:newLocation.coordinate.longitude], @"longitude",
nil];
[[NSUserDefaults standardUserDefaults] setValue:dictValue forKey:@"MY_LOCATION"];
CLLocationDistance meters = [newLocation distanceFromLocation:oldLocation];
if (meters >= kThresholdDistance ) {
[self.delegate locationUpdate:newLocation];
}
}
- (void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
[self.delegate locationError:error];
}
@end
To use it in few controller .Adapt delegate in it's .h file and use like as follows :
- (void) initializeLocations
{
MyLocation _myLocation = [[MyLocation alloc] init];
_myLocation.delegate = self;
_myLocation.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
CLLocation * currentLocation = _myLocation.locationManager.location;
// Updating user's current location to server
[self sendUserCurrentCoordinate:currentLocation.coordinate];
// start updating current location
_myLocation.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[_myLocation.locationManager startUpdatingLocation];
[_myLocation.locationManager startUpdatingLocation];
}
- (void)locationUpdate:(CLLocation *)location {
NSLog(@"location %@", location);
}
- (void)locationError:(NSError *)error {
NSLog(@"locationdescription %@", [error description]);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With