when usage tutorial startupdatinglocation manager example description current cllocationmanagerdelegate ios objective-c gps cllocationmanager

ios - usage - startupdatinglocation swift



Objetivo C, iOS 7-CLLocationManager: didUpdateLocations se llama una sola vez (3)

En primer lugar, si está navegando, debería registrarse para recibir notificaciones de cambios importantes. Ve a leer la documentación sobre eso aquí . Es mucho más eficiente. Tendrás que apagarlo cuando no lo estés usando, pero es mucho mejor. El soporte para esto se remonta a iOS 4. Eso es seguro para el 99% de la población de usuarios.

EDITAR: Ok, me acabo de dar cuenta de que el problema es exclusivo de iOS 7. Todavía no puedo resolverlo, así que supongo que lo intentaré con las siguientes sugerencias. ¡Gracias a todos!

¡Hola! Estoy programando una aplicación de navegador, y necesito actualizar la posición del usuario siempre que sea posible. Tengo dos controladores de vista que usan CLLocation Manager. En ambos he agregado esta línea:

#import <CoreLocation/CoreLocation.h>

Y luego agregué la declaración a la interfaz, y estoy configurando esto como una propiedad en el archivo .h, y sintetizando después:

@property (strong, nonatomic) CLLocationManager *locationManager;

Después de eso, estoy lanzando de locationManager en viewDidLoad, de esta manera:

if(self){ locationManager = [[CLLocationManager alloc] init]; //locationManager.delegate = self; [locationManager setDelegate:self]; [locationManager setDistanceFilter:kCLHeadingFilterNone]; [locationManager setDesiredAccuracy:kCLLocationAccuracyBestForNavigation]; [locationManager startUpdatingLocation]; }

Y aquí están mis métodos de delegado.

Para la primera Vista:

#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) { homeLatitude = [[NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude] doubleValue]; homeLongitude = [[NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude] doubleValue]; NSLog(@"Updated! -> hl = %f, hlg = %f", homeLatitude, homeLongitude); } }

Para la segunda vista. Como puede ver, reemplacé el viejo didUpdateToLocation con didUpdateLocations, como un intento desesperado.

#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) { NSLog(@"Tarzan boy"); _testLabel.text = [NSString stringWithFormat:@"Oh DAMN!!!!"]; } }*/ -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { NSLog(@"didUpdateToLocation: %@", [locations lastObject]); CLLocation *currentLocation = [locations lastObject]; if (currentLocation != nil) { currentLatitude = [[NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude] doubleValue]; currentLongitude = [[NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude] doubleValue]; NSLog(@"Updated! (MapWithRoutesViewController) -> hl = %f, hlg = %f", currentLatitude, currentLongitude); _testLabel.text = [NSString stringWithFormat:@"Update! -> hl = %f, hlg = %f", currentLatitude, currentLongitude]; //Aquí es donde borramos el lugar al que llegaron. if(mapView){ if(followMe){ CLLocationCoordinate2D *c = &((CLLocationCoordinate2D){.latitude = currentLatitude, .longitude = currentLongitude}); [mapView.mapView as_setCenterCoordinate:*c zoomLevel:32 animated:NO]; _ourStepper.value = [mapView.mapView as_zoomLevel]; } if([mapView getNearestDestinyDistance:currentLocation] < 150.0){ NSLog(@"Hay que eliminar el primer destino del MapView"); mapView.destinoActual++; } if([mapView getNearestPointDistance:currentLocation] > 200.0){ NSLog(@"Hay que recalcular la ruta al destinoActual"); SpinnerView *spinner = [SpinnerView loadSpinnerIntoView:self.view]; spinner.tag = 98; while (![mapView recalculateRoutesTo:currentLocation]) { //do nothin... } [spinner removeSpinner]; } } } //[locationManager stopUpdatingLocation]; }

Como puedes ver, la línea

//[locationManager stopUpdatingLocation];

es comentado Bueno, el problema es que me está volviendo loco es que el código anterior funciona como un encanto en el controlador de la primera vista, y se actualiza periódicamente como esperaba. Pero en la segunda vista, funciona solo la primera vez y nunca se actualiza nuevamente. Programé estos métodos en diferentes momentos, así que no puedo recordar si hice algo en la primera vista que no hice en el segundo. Pero están en la misma aplicación, así que supongo que no hay problema con las bibliotecas o permisos. Cualquier ayuda o pista es bienvenida, ¡gracias!


Tuve una situación similar en mi aplicación e implementé un singleton que maneja todas las actualizaciones de ubicación y luego desactiva NSNotificaitons para los hilos de primer plano.

  • Crear una clase singleton que maneje las actualizaciones de ubicación View
  • regístrese para escuchar LOCATION_CHANGE actualizaciones quizás Background
  • el objeto singleton se registra como el delegado para el administrador de ubicación

Puede que esta no sea la respuesta que está buscando, pero sé que funcionó en mi caso.


Encontré la solución aquí . El locationManager funciona cuando lo ejecuto de esta manera:

if(self){ locationManager = [[CLLocationManager alloc] init]; [locationManager setDelegate:self]; [locationManager setDistanceFilter:kCLHeadingFilterNone]; //change the desired accuracy to kCLLocationAccuracyBest [locationManager setDesiredAccuracy:kCLLocationAccuracyBest]; //SOLUTION: set setPausesLocationUpdatesAutomatically to NO [locationManager setPausesLocationUpdatesAutomatically:NO]; [locationManager startUpdatingLocation]; }

Voy a trabajar de todos modos en el rendimiento como sugirió Rob. ¡Gracias a todos por la ayuda!