Search code examples
ioscore-locationcllocationmanagernsnotificationcenterappdelegate

Update current location in all views from navbar locationButton


I have a custom navbar with a locateButton that is visible in every view

enter image description here

When a user taps the locateButton, I would like to update lat and long on every view. I've got it working in one view at a time, with the following code.

ViewController.m

- (UIBarButtonItem *)locateButton {
    [locationButton addTarget:self action:@selector(locationPressed:) forControlEvents:UIControlEventTouchUpInside];       
} 

- (IBAction)locationPressed:(id)sender {
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    [locationManager startUpdatingLocation];
}

#pragma mark - CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
    NSLog(@"didFailWithError: %@", error);
    UIAlertView *errorAlert = [[UIAlertView alloc]
                               initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [errorAlert show];
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    NSLog(@"didUpdateToLocation: %@", newLocation);
    CLLocation *currentLocation = newLocation;

    if (currentLocation != nil) {
        latLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
        longLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
    }

    // Stop Location Manager
    [locationManager stopUpdatingLocation];

    // Reverse Geocoding
    NSLog(@"Resolving the Address");
    [geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
        NSLog(@"Found placemarks: %@, error: %@", placemarks, error);
        if (error == nil && [placemarks count] > 0) {
            placemark = [placemarks lastObject];
            addressLabel.text = [NSString stringWithFormat:@"%@, %@",
                                 placemark.locality,
                                 placemark.administrativeArea];
            addressLabel.numberOfLines = 0;



        } else {
            NSLog(@"%@", error.debugDescription);
        }
    } ];

I'm trying to add a singleton to accomplish this.

In Location.h

//  Location.h


#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>



@interface Location : NSObject <CLLocationManagerDelegate>

@property (nonatomic, strong) CLLocationManager* locationManager;

+ (Location*)sharedSingleton;


@end

Then in Location.M

//  Location.m


#import "Location.h"

@implementation Location

@synthesize locationManager;


- (id)init {
    self = [super init];

    if(self) {
        self.locationManager = [CLLocationManager new];
        [self.locationManager setDelegate:self];
        [self.locationManager setDistanceFilter:kCLDistanceFilterNone];
        [self.locationManager setHeadingFilter:kCLHeadingFilterNone];
        [self.locationManager startUpdatingLocation];
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        //do any more customization to your location manager
    }

    return self;
}

+ (Location*)sharedSingleton {
    static Location* sharedSingleton;
    if(!sharedSingleton) {
        @synchronized(sharedSingleton) {
            sharedSingleton = [Location new];
        }
    }

    return sharedSingleton;
}

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    NSLog(@"didUpdateToLocation: %@", newLocation);
    [locationManager stopUpdatingLocation];

}

@end

How do I get my - (IBAction)locationPressed:(id)sender in another view let's say HomeViewController.m to call this locationManager method and also update the singleton value?


Solution

  • You might consider a singleton as your location manager and location manager delegate. There are a bunch of stackoverflow questions about creating singletons like this one: Singleton in iOS 5?.

    Then when your user clicks that button, your singleton class will be called and updated and other views will look at that same singleton to get their location info.