答えは、あなたがそれが振る舞うように処理を書く必要があるということでした。
私はこの一般的な問題について読みました。「力」とは、電話に最適な条件下で信頼できる位置を与える明確な動作を開始することを意味することを明確にすべきでした。忙しくない-満足するまで待つか、すぐに結果/エラーコードを期待します。
常識的な観点から、すべての開発者が望むのは、少なくともパラメータ内の位置を要求し、それが有効で正確な範囲内であるか、キャンセルされた場合、またはタイムアウトした場合にのみコールバックする追加のメソッドです。条件によってそれが妨げられる場合は、カスタムコードで処理できるようにするために、難解な動作をテストする必要はありません。
これについて質問する必要があった理由は次のとおりです。
上記のように機能するメソッドは存在しません
本のコードを使用する(その他のiPhone 3開発)
それを最初から書くとき(LocateMe.xprojを見て)、それを発見します:
シミュレーターの動作は電話の動作とは異なります(位置自体については話しません。これは明らかにIPルックアップで可能な限り優れていますが、didUpdateToLocationの動作です)。シミュレータの制限を認識して、メソッドは少なくともデバイスでの動作と同じように動作する必要があります。ただし、現在、正しく記述されたロケーション処理/チェックコードはシミュレーターでタイムアウトしますが(LocateMeの例のように)、誤ったコード(1回要求してコールバックでnewLocationを使用)は機能します。
[locationManagerstopUpdatingLocation]の後にdidUpdateToLocationが2回呼び出される原因となるバグ。
これに加えて、(私のように)自分の位置に基づいてデータをロードし、そのデータがアプリケーションの複数のビューで必要な場合、Appleのロケーションフェッチメソッドの動作では、更新のチェーンを簡単に処理できません- load-calculate-アプリ全体で一貫して問題なく表示されます。特に、ユーザー/上司の認識や、それがどのように機能するか(岩)とシステムがどのように機能するか(難しい場所)の決定の間に行き詰まっている場合。
これが、デバイスとシミュレーターで動作する私の現在のコードです。
//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秒などの短い値に設定することをお勧めします。これは、古いが比較的使用可能な位置であり、タイムアウトになるまではそれ以上ないためです。
編集:あなたが私のコードを最もよくするか、省略を指摘することができるなら、私はそれを答えとしてマークします、私は自分自身を答えとしてマークするのが嫌いです。