Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it necessary to use a singleton CLLocationManager to avoid waiting for the device location to update?

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?

like image 253
user Avatar asked Nov 12 '22 21:11

user


1 Answers

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

}
like image 114
Vinodh Avatar answered Nov 24 '22 11:11

Vinodh