Ответ состоял в том, что вам нужно написать обработчик так, как вы хотите, чтобы он вел себя.
Я прочитал об этой распространенной проблеме.Я должен был уточнить, что «сила» означает , чтобы начать однозначное поведение, которое дает надежную позицию при оптимальных условиях для телефона.Не занят - ждать, пока не будет выполнено, или ожидать немедленного результата / кода ошибки.
С точки зрения здравого смысла, то, что было бы желательно для всех разработчиков, было бы, по крайней мере, дополнительным методом, чтобы просто запросить позицию в пределахпараметры и обратный вызов только тогда, когда он действителен и в пределах точности, или отменен, или истек тайм-аут.Если условия препятствуют этому, вам не нужно проверять эзотерическое поведение, чтобы иметь возможность обрабатывать его с помощью пользовательского кода.
Почему мне вообще нужно было спросить об этом:
не существует метода, функционирующего как описано выше
с использованием кода из книги (More Iphone 3 Development)
принаписав его с нуля (глядя на LocateMe.xproj), обнаружив, что:
поведение симулятора отличается от поведения телефона (не говоря уже о самой позиции, которая, очевидно, так же хороша, как и поиск по ipсделать это, но поведение didUpdateToLocation).Признавая ограничения симулятора, метод должен, по крайней мере, вести себя как на устройстве.Но в настоящее время правильно написанный код обработки / проверки местоположения просто теряет время ожидания в симуляторе (как в примере LocateMe), в то время как неправильный код (запрашивая один раз и используя newLocation при обратном вызове) работает.
и ошибка, приводившая к тому, что didUpdateToLocation вызывался дважды после [locationManager stopUpdatingLocation];
Если в дополнение к этому вы (как и я) загружаете данные, основанные на вашей позиции, и данные требуются для несколькихПо мнению вашего приложения, поведение методов извлечения местоположения Apple не позволяет легко обрабатывать цепочку обновления-загрузки-вычисления-присутствия последовательно и без проблем во всем приложении.Особенно, если вы застряли между восприятием пользователя / босса или решением о том, как оно должно работать (скала) и как работает система (трудное место).
Вот мой текущий код, который работает на устройстве ив симуляторе:
//ask for a position, as fresh as possible.
-(void)updateMeMap {
lastloc.coordinate=homeloc.coordinate;
lm.delegate=self;
ctr=0;
[self performSelector:@selector(stopUpd) withObject:nil afterDelay:gpstimeout];
[lm startUpdatingLocation];
}
//called on each position update.
-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
ctr++;
if (ctr<15) {
NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
NSLog(@"%d",ctr);
if (locationAge<60) {
NSLog(@"Found");
ctr=40;
homeloc.coordinate=newLocation.coordinate;
[self stopUpd];
[self reload];
} else {
NSLog(@"Lastupd");
lastloc.coordinate=newLocation.coordinate;
}
} else {
//enough tries, if not canceled choose lastloc.
if (ctr<40) {
NSLog(@"Last");
ctr=40;
homeloc.coordinate=lastloc.coordinate;
[self stopUpd];
[self reload];
}
}
}
//force stop updates. ctr prevents extra calls after stopUpdatingLocation.
//called after the timeout delay, if position found, cancel the timeout.
-(void)stopUpd {
[lm stopUpdatingLocation];
lm.delegate=nil;
if (ctr<15) {
ctr=40; //2 extra calls after stopupda... otherwise, now do nothing.
NSLog(@"Timeout");
homeloc.coordinate=lastloc.coordinate; //@need "copy"?
[self reload];
} else {
ctr=40; //2 extra calls after stopupda... otherwise, now do nothing.
[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(stopUpd) object:nil];
}
}
// "couldn't get userlocation" handler. I also cancel like this on connectionDidFailWithError.
-(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
NSLog(@"Location failed: %@",[error localizedDescription]);
ctr=0;
[self stopUpd];
}
Там, где есть ctr для предотвращения 2 дополнительных вызовов, lastloc - последняя известная надежная позиция, homeloc - позиция телефона, используемая для (поточной) загрузки данных, специфичных для местоположенияс [перезагрузить себя].
Константы 15 и 60 являются безопасными значениями из реальных испытаний;gpstimeout установлен на 30. Если вы много работаете в симуляторе, вы можете установить его на что-то короткое, например, на 3 секунды, поскольку все, что вы получите, это устаревшая, но относительно полезная позиция, и не более до истечения времени ожидания.
Редактировать: Если вы можете улучшить мой код или указать на упущение, я отмечу это как ответ, я ненавижу отмечать мой собственный как ответ.