Как остановить многократный вызов метода didUpdateLocations () в ios

Это мой код......

 -(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;
 }

этот метод вызывает несколько раз, которые я не хочу.....

10 ответов


добавьте туда некоторые ограничения. Для timespan между местоположениями и точностью

-(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

}

выделить код


самый простой способ:

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
{
   [manager stopUpdatingLocation];
    manager.delegate = nil;

   //...... do something

}

менеджер не может найти ваш didUpdateLocations способ без делегат ссылка: - D

но не забудьте установить его снова перед использованием startUpdatingLocation


У меня похожая ситуация. Вы можете использовать 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
    });
}

вы можете использовать статическую переменную для хранения последней метки времени местоположения, а затем сравнить ее с новейшей, например:

- (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
}

напишите этот метод, когда вы хотите остановить обновление location manager

[locationManager stopUpdatingLocation];

для ограничения по времени я не понял код из принятого ответа, разместив другой подход. как отмечает Роб, "когда вы впервые запускаете службы определения местоположения, вы можете видеть, что он вызывается несколько раз". приведенный ниже код действует на первое местоположение и игнорирует обновленные местоположения в течение первых 120 секунд. это один из способов решить исходный вопрос "как остановить многократный вызов метода didUpdateLocations".

in .H-файл:

@property(strong,nonatomic) CLLocation* firstLocation;

in .м файл:

// 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

вы можете установить флаг (Bool). При создании экземпляра locationsManager установите флаг = true, когда locationManager: didupdatelocations возвращается внутри блока кода что вы хотите запустить только один раз, установите flag = false. Таким образом, он будет запущен только один раз.

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

диспетчер локаций будет вызываться несколько раз, но код, который вы хотите выполнить только один раз, и я думаю, что это то, что вы пытаетесь достичь?


locationManager.startUpdatingLocation () непрерывно извлекает местоположение и несколько раз вызывает метод didUpdateLocations, Просто установите значение для locationManager.значение distanceFilter перед вызовом locationManager.startUpdatingLocation().

по мере того как я установил 200 метров(вы можете изменить как ваше требование) работая отлично

    locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.distanceFilter = 200
    locationManager.requestWhenInUseAuthorization()
    locationManager.startUpdatingLocation()

вы можете писать : [менеджер stopUpdatingLocation]; manager = nil; в делегате didupdatelocation