Как остановить многократное вызов метода 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;
}
Этот метод вызывает многократное обращение, которое я не хочу.....
Ответы
Ответ 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