Brandon
Brandon

Reputation: 2171

Access User's Location Once in viewDidAppear Method

I have two different UIViewControllers that need access to the user's Latitude and Longitude. I only need to access the location once when the view appears. I am currently storing the LocationManager in the app delegate, but the viewDidAppear: method loads too quickly for the user's location to be found. Does anyone know the best way to go about this? Thank you!

Upvotes: 0

Views: 156

Answers (2)

meaning-matters
meaning-matters

Reputation: 22936

Sound like a typical case where NSNotifications are useful. I believe that CoreLocation does not send notifications. In that case you'll have to do it yourself. In AppDelegate.h you define:

const string* LocationUpdateNotification  = @"LocationUpdateNotification";

Then in the your CoreLocation delegate method in AppDelegate.m you do:

dispatch_async(dispatch_get_main_queue(), ^
{
    [[NSNotificationCenter defaultCenter] postNofificationName:LocationUpdateNotification 
                                                        object:self];
});

Finally in each of your view controllers:

    [[NSNotificationCenter defaultCenter] addObserverForName:MyNotification
                                                      object:nil
                                                       queue:[NSOperationQueue mainQueue]
                                                  usingBlock:^(NSNotification* note)
    {
        // YOUR LOCATION UPDATE CODE.
    }];

Upvotes: 1

Roland Keesom
Roland Keesom

Reputation: 8288

I create a shared LocationManager. Then startUpdatingLocation and stopUpdatingLocation after you get a callback.

Here is the code I use:

In your appDelegate add the following method:

+ (NHAppDelegate *)sharedDelegate
{
    return (NHAppDelegate *)[[UIApplication sharedApplication] delegate];
}

And make the LocationManager available:

@property (nonatomic, strong) CLLocationManager *locationManager;

Then in your UIViewController you can do:

[NHAppDelegate sharedDelegate].locationManager.delegate = self;
[[NHAppDelegate sharedDelegate].locationManager startUpdatingLocation];

Then I use the following code to get the location and display it in a UILabel.

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    [self loadPositionWithLocation:newLocation];
}

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    CLLocation *location = [locations objectAtIndex:0];
    [self loadPositionWithLocation:location];
}

-(void)loadPositionWithLocation:(CLLocation *)newLocation
{
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    [geocoder reverseGeocodeLocation:newLocation completionHandler:
     ^(NSArray* placemarks, NSError* error){
         if ([placemarks count] > 0)
         {
             CLPlacemark *placemark = [placemarks objectAtIndex:0];

             NSString *thoroughfare = placemark.thoroughfare;
             NSString *subThoroughfare = placemark.subThoroughfare;
             NSString *postalCode = placemark.postalCode;
             NSString *locality = placemark.locality;

             if( thoroughfare == nil )      {  thoroughfare = @"";     }
             if( subThoroughfare == nil )   {  subThoroughfare = @"";  }
             if( postalCode == nil )        {  postalCode = @"";       }
             if( locality == nil )          {  locality = @"";         }

             NSString *addressString = [NSString stringWithFormat:@"%@ %@\n%@ %@", thoroughfare, subThoroughfare, postalCode, locality];

             self.positionLabel.text = addressString;

             [[NHAppDelegate sharedDelegate].locationManager stopUpdatingLocation];
         }
     }];
}

Important is the last line stopUpdatingLocation so the LocationManager only gets called once.

Upvotes: 1

Related Questions