Quello che faccio è implementare una classe singleton per gestire gli aggiornamenti dalla posizione principale. Per accedere alla mia posizione attuale, faccio un CLLocation *myLocation = [[LocationManager sharedInstance] currentLocation];
Se si voleva bloccare il thread principale si potrebbe fare qualcosa di simile:
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
}
Tuttavia, come è stato già sottolineato, bloccare il thread principale non è probabilmente un buona idea, ma questo può essere un buon punto di partenza mentre stai costruendo qualcosa. Noterai inoltre che la classe che ho scritto controlla il timestamp sugli aggiornamenti di posizione e ignora quelli vecchi, per prevenire il problema di ottenere dati obsoleti dalla posizione principale.
Questa è la classe singleton che ho scritto. Si noti che è un po 'approssimativo:
#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
fonte
2009-01-20 20:27:16
Si dovrebbe chiarire la questione: se si sa come utilizzare CLLocationManager - qual è il problema nell'implementazione di un tale "metodo di convenienza"? – tcurdt
Penso che il problema sia che non è così facile. Normalmente restituisce prima una vecchia posizione, seguita da una molto selvaggia, seguita da una progressivamente migliore, a che punto si decide di avere quella che si desidera? Dipende solo da te. – rustyshelf
Buon punto, arrugginito! –