Lo que hago es implementar una clase singleton para administrar las actualizaciones desde la ubicación central. Para tener acceso a mi ubicación actual, hago un CLLocation *myLocation = [[LocationManager sharedInstance] currentLocation];
Si quisiera bloquear el hilo principal se podría hacer algo como esto:
while ([[LocationManager sharedInstance] locationKnown] == NO){
//blocking here
//do stuff here, dont forget to have some kind of timeout to get out of this blocked //state
}
Sin embargo, como ya se ha señalado, bloqueando el hilo principal no es probablemente una buena idea, pero este puede ser un buen punto de partida a medida que construyes algo. También notará que la clase que escribí verifica la marca de tiempo en las actualizaciones de ubicación e ignora las que son antiguas, para evitar el problema de obtener datos obsoletos desde la ubicación del núcleo.
Esta es la clase singleton que escribí. Tenga en cuenta que es un poco difícil en los bordes:
#import <CoreLocation/CoreLocation.h>
#import <Foundation/Foundation.h>
@interface LocationController : NSObject <CLLocationManagerDelegate> {
CLLocationManager *locationManager;
CLLocation *currentLocation;
}
+ (LocationController *)sharedInstance;
-(void) start;
-(void) stop;
-(BOOL) locationKnown;
@property (nonatomic, retain) CLLocation *currentLocation;
@end
@implementation LocationController
@synthesize currentLocation;
static LocationController *sharedInstance;
+ (LocationController *)sharedInstance {
@synchronized(self) {
if (!sharedInstance)
sharedInstance=[[LocationController alloc] init];
}
return sharedInstance;
}
+(id)alloc {
@synchronized(self) {
NSAssert(sharedInstance == nil, @"Attempted to allocate a second instance of a singleton LocationController.");
sharedInstance = [super alloc];
}
return sharedInstance;
}
-(id) init {
if (self = [super init]) {
self.currentLocation = [[CLLocation alloc] init];
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[self start];
}
return self;
}
-(void) start {
[locationManager startUpdatingLocation];
}
-(void) stop {
[locationManager stopUpdatingLocation];
}
-(BOOL) locationKnown {
if (round(currentLocation.speed) == -1) return NO; else return YES;
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
//if the time interval returned from core location is more than two minutes we ignore it because it might be from an old session
if (abs([newLocation.timestamp timeIntervalSinceDate: [NSDate date]]) < 120) {
self.currentLocation = newLocation;
}
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
UIAlertView *alert;
alert = [[UIAlertView alloc] initWithTitle:@"Error" message:[error description] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
}
-(void) dealloc {
[locationManager release];
[currentLocation release];
[super dealloc];
}
@end
Debe aclarar la pregunta: ¿Si sabe cómo utilizar CLLocationManager - ¿Cuál es el problema al implementar un "método de conveniencia"? – tcurdt
Creo que el problema es que no es tan fácil. Normalmente, primero devuelve una ubicación anterior, seguida de una muy inexacta, seguida de otras progresivamente mejores, ¿en qué momento decides que tienes la que quieres? Depende de ti. – rustyshelf
¡Buen punto, oxidado! –