Подтвердить что ты не робот

Как остановить многократное вызов метода 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;
 }

Этот метод вызывает многократное обращение, которое я не хочу.....

4b9b3361

Ответ 1

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

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

}

Ответ 2

При распределении вашего объекта LocationManager вы можете установить свойство distanceFilter для LocationManager. Свойство "Расстояние-фильтр" - это значение CLLocationDistance, которое может быть установлено для уведомления диспетчера местоположений о расстоянии, перемещенном в метрах. Вы можете установить фильтр расстояния следующим образом:

LocationManager *locationManger = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = 100.0; // Will notify the LocationManager every 100 meters
locationManager.desiredAccuracy = kCLLocationAccuracyBest;

Ответ 3

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

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

   //...... do something

}

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

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

Ответ 4

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

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

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

Ответ 6

Запишите этот метод, когда вы хотите остановить обновление диспетчера местоположений

[locationManager stopUpdatingLocation];

Ответ 7

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

в .h файле:

@property(strong,nonatomic) CLLocation* firstLocation;

в .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

Ответ 8

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

 if flag == true {
     flag = false
    ...some code probably network call you only want to run the once 
    }
Менеджмент местоположений

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

Ответ 9

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

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

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

Ответ 10

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