Reputation: 2171
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
Reputation: 22936
Sound like a typical case where NSNotification
s 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
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