olvide - Cómo detener varias veces el método de llamada de didUpdateLocations() en ios
me olvide el codigo de restricciones del iphone (10)
Este es mi código ......
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
location_updated = [locations lastObject];
NSLog(@"updated coordinate are %@",location_updated);
latitude1 = location_updated.coordinate.latitude;
longitude1 = location_updated.coordinate.longitude;
self.lblLat.text = [NSString stringWithFormat:@"%f",latitude1];
self.lblLon.text = [NSString stringWithFormat:@"%f",longitude1];
NSString *str = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/geocode/json?latlng=%f,%f&sensor=false",latitude1,longitude1];
url = [NSURL URLWithString:str];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
connection = [NSURLConnection connectionWithRequest:request delegate:self];
if (connection)
{
webData1 = [[NSMutableData alloc]init];
}
GMSMarker *marker = [[GMSMarker alloc] init];
marker.position = CLLocationCoordinate2DMake(latitude1,longitude1);
marker.title = formattedAddress;
marker.icon = [UIImage imageNamed:@"m2.png"];
marker.map = mapView_;
marker.draggable = YES;
}
Este método es llamado varias veces que no quiero .....
Añadir alguna restricción allí. Para el intervalo de tiempo entre ubicaciones y precisión
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *newLocation = locations.lastObject;
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
if (locationAge > 5.0) return;
if (newLocation.horizontalAccuracy < 0) return;
// Needed to filter cached and too old locations
//NSLog(@"Location updated to = %@", newLocation);
CLLocation *loc1 = [[CLLocation alloc] initWithLatitude:_currentLocation.coordinate.latitude longitude:_currentLocation.coordinate.longitude];
CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:newLocation.coordinate.latitude longitude:newLocation.coordinate.longitude];
double distance = [loc1 distanceFromLocation:loc2];
if(distance > 20)
{
_currentLocation = newLocation;
//significant location update
}
//location updated
}
Al asignar el objeto LocationManager
, puede establecer la propiedad distanceFilter
del LocationManager
. La propiedad de filtro de distancia es un valor CLLocationDistance
que se puede configurar para notificar al administrador de ubicación la distancia recorrida en metros. Puede configurar el filtro de distancia de la siguiente manera:
LocationManager *locationManger = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = 100.0; // Will notify the LocationManager every 100 meters
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
Escribe este método cuando quieras dejar de actualizar el administrador de ubicación.
[locationManager stopUpdatingLocation];
La forma más fácil:
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
[manager stopUpdatingLocation];
manager.delegate = nil;
//...... do something
}
El administrador no puede encontrar su método didUpdateLocations sin la referencia del delegado :-D
Pero no olvide volver a configurarlo antes de usar startUpdatingLocation
Puedes usar una variable estática para almacenar la última marca de tiempo de ubicación y luego compararla con la más nueva, como esto:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
[manager stopUpdatingLocation];
static NSDate *previousLocationTimestamp;
CLLocation *location = [locations lastObject];
if (previousLocationTimestamp && [location.timestamp timeIntervalSinceDate:previousLocationTimestamp] < 2.0) {
NSLog(@"didUpdateLocations GIVE UP");
return;
}
previousLocationTimestamp = location.timestamp;
NSLog(@"didUpdateLocations GOOD");
// Do your code here
}
Tengo una situación similar. Puedes usar dispatch_once:
static dispatch_once_t predicate;
- (void)update
{
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined &&
[_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[_locationManager requestWhenInUseAuthorization];
}
_locationManager.delegate = self;
_locationManager.distanceFilter = kCLDistanceFilterNone;
_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
predicate = 0;
[_locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
[manager stopUpdatingLocation];
manager = nil;
dispatch_once(&predicate, ^{
//your code here
});
}
Usted podría establecer una bandera (Bool). Cuando crea una instancia de la ubicación de su administrador de bandera set = true, entonces, cuando el administrador de ubicación: didUpdateLocations retorna dentro de un bloque de código que desea ejecutar solo una vez set flag = false. De esta manera solo se ejecutará una vez.
if flag == true {
flag = false
...some code probably network call you only want to run the once
}
Se llamará al administrador de ubicaciones varias veces, pero el código que desea ejecutar solo una vez, y creo que eso es lo que está intentando lograr.
locationManager.startUpdatingLocation () recupera la ubicación continuamente y las llamadas del método didUpdateLocations varias veces. Simplemente configure el valor para el valor de locationManager.distanceFilter antes de llamar a locationManager.startUpdatingLocation ().
Como puse 200 metros (puede cambiar según sus necesidades) trabajando bien
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = 200
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
para la restricción de tiempo, no entendí el código de la respuesta aceptada, publicando un enfoque diferente. como Rob señala "Cuando inicias los servicios de ubicación por primera vez, puedes verlos llamados varias veces". el código siguiente actúa en la primera ubicación e ignora las ubicaciones actualizadas durante los primeros 120 segundos. Es una forma de abordar la pregunta original "Cómo detener varias veces la llamada de método de didUpdateLocations".
en el archivo .h:
@property(strong,nonatomic) CLLocation* firstLocation;
en el archivo .m:
// is this the first location?
CLLocation* newLocation = locations.lastObject;
if (self.firstLocation) {
// app already has a location
NSTimeInterval locationAge = [newLocation.timestamp timeIntervalSinceDate:self.firstLocation.timestamp];
NSLog(@"locationAge: %f",locationAge);
if (locationAge < 120.0) { // 120 is in seconds or milliseconds?
return;
}
} else {
self.firstLocation = newLocation;
}
// do something with location
puede escribir: [manager stopUpdatingLocation]; manager = nil; en didupdatelocation delegate