Cómo detener varias veces llamada al método de didUpdateLocations() en ios

Esta 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 llamar varias veces que no quiero…..

  • Entonces ¿por qué llamar a este método?
  • Para la ubicación de la actualización después de que cada cinco minutos.
  • Cuando empiece a servicios de ubicación, puede ver se llama varias veces con cada vez más lugares precisos (por ejemplo, la disminución de horizontalAccuracy). También se establece CLLocationManager propiedades distanceFilter y desiredAccuracy para el control de la frecuencia con que esta se llama.
  • Swift 3 versión de aceptado responder stackoverflow.com/a/43066729/7250862
InformationsquelleAutor | 2014-03-10

10 Kommentare

  1. 22

    Agregar algunos restricción de allí. Para el intervalo de tiempo entre las ubicaciones y exactitud

    -(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
    
    }
    • Es mejor moverse en una línea: if(distance > 20) { _currentLocation = newLocation; //significant location update }
    • gracias pero tengo una pregunta para el código : if (newLocation.horizontalAccuracy < 0) return; ¿Qué quiere usted decir?
    • Estaba tratando de filtro de ubicaciones incorrectas (en ese caso la precisión es malo para ellos)
    • ¿DidFailWithError ya que no hay actualizada de lugares?
  2. 37

    Mientras que la asignación de su LocationManager objeto puede establecer el distanceFilter propiedad de la LocationManager. Distancia de la propiedad filter es un CLLocationDistance valor que se puede configurar para notificar la ubicación del administrador acerca de la distancia recorrida en metros. Usted puede ajustar la distancia de filtro 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;
    • tengo que probar esto, pero este no funciona…
    • Lo que realmente hace el trabajo.
    • Deja de ubicación de la actualización en el primer lugar, mientras que la respuesta seleccionada simplemente se detiene su posterior manipulación, así que creo que esta debe ser la mejor opción
    • excelente respuesta. Yo nunca entiendo cómo la gente piensa que el establecimiento de un retorno sttmnt en el comienzo de la función de resolver algo….
    • funciona, gracias
    • no trabajo para mí, siempre consigue 3 actualizaciones al principio

  3. 21

    La manera 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 didUpdateLocations método sin el delegado de referencia 😀

    Pero no olvide ajustar de nuevo antes de usar startUpdatingLocation

    • esto funciona perfectamente ya que sólo actualiza la ubicación de una vez en una instancia específica del gerente.. gracias!
    • por qué no simplemente usar locationManager.requestLocation() para obtener la localización de una vez? stopUpdatingLocation dentro de didUpdateLocations no tiene mucho sentido, probablemente sólo como una solución en iOS8 (donde .requestLocation() no está disponible)
    • bonita respuesta, muchas gracias
  4. 10

    He similar situación. Usted puede utilizar 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
        });
    }
  5. 1

    Puede utilizar una variable estática a la tienda de la última ubicación de la marca de hora y luego se compara con la más reciente, como este:

    - (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
    }
    • está trabajando en el modo suspendido?
    • el modo suspendido? De qué están tratando de hacer? Si desea asegurarse de que funcionará en el fondo, usted debe comenzar a una UIBackgroundTask. Si desea controlar las actualizaciones de ubicación, usted debe utilizar startMonitoringSignificantLocationChanges.
    • lo mismo he hecho UIBackgroundTask gracias por la repetición. 🙂
  6. 0

    para la restricción de tiempo, no he entendido el código de aceptado respuesta, la publicación de un enfoque diferente. como Rob señala «Cuando empiece a servicios de ubicación, puede ver se llama varias veces». el siguiente código de actos en el primer lugar, y omite la actualización de ubicaciones para los primeros 120 segundos. es una forma de dirección original de la pregunta «¿Cómo detener varias veces llamada al método de didUpdateLocations».

    en .h archivo:

    @property(strong,nonatomic) CLLocation* firstLocation;

    en .m de archivo:

    //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
    • está trabajando en el modo suspendido?
    • no sé responder a tu pregunta, me mudé a un proyecto diferente.
  7. 0

    Puede establecer un indicador (Bool). Cuando se crean instancias de su locationsManager set flag = true entonces cuando locationManager:didUpdateLocations devuelve dentro de un bloque de código
    que desea que se ejecute sólo una vez ajustado bandera = false. De esta manera que sólo se ejecute una vez.

     if flag == true {
         flag = false
        ...some code probably network call you only want to run the once 
        }

    lugares administrador será llamado varias veces pero el código que se desea ejecutar sólo una vez, y creo que eso es lo que estamos tratando de lograr?

  8. 0

    locationManager.startUpdatingLocation() captura de ubicación de forma continua y didUpdateLocations método llama varias veces,
    Sólo tienes que configurar el valor para locationManager.distanceFilter valor antes de llamar locationManager.startUpdatingLocation().

    Como yo, situada a 200 metros(se puede cambiar como su requisito) trabajando bien

        locationManager = CLLocationManager()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.distanceFilter = 200
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
    • voy a aplicar esto, pero la llamada 3 tiempo cuando el lugar de inicio de la actualización
  9. 0

    se puede escribir :
    [administrador de stopUpdatingLocation];
    administrador = nil;
    en didupdatelocation delegado

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea