3

CoreLocationを使用してユーザーの位置を常に追跡する必要があるiPhoneアプリを作成しようとしています。startMonitoringSignificantLocationChangesを使用しているのは、バックグラウンドで更新され、大幅な変更があるたびに更新されるほど精度が重要ではないためです。

現在、場所を更新するためにWebサービスにHTTPリクエストを送信しています。これは、アプリを実行しているときに完全に機能します-位置データを保存しているMySQLデータベースで位置情報が更新されます。しかし、アプリがバックグラウンドに入ると、電話の右上隅に位置情報サービスのアイコンが表示されますまだ実行中ですが、戻ってデータベースを見ると、場所がまったく更新されませんでした。私はこれをテストするために、アプリを実行している状態とアプリをバックグラウンドで実行している状態で、街をドライブしました。

Appleのドキュメントから:

このサービスを実行したままにして、アプリケーションが後で一時停止または終了した場合、新しい位置データが到着すると、サービスはアプリケーションを自動的にウェイクアップします。ウェイクアップ時に、アプリケーションはバックグラウンドに置かれ、位置データを処理するために少し時間が与えられます。アプリケーションはバックグラウンドにあるため、最小限の作業を実行し、割り当てられた時間が経過する前にアプリケーションが戻るのを妨げる可能性のあるタスク(ネットワークのクエリなど)を回避する必要があります。そうでない場合、アプリケーションが終了する可能性があります。

この「位置データを処理するためのわずかな時間」は正確にどのくらいですか?また、ネットワークにクエリを実行することはお勧めしませんか、それともその時点でネットワークにクエリを実行することはできませんか?アプリがバックグラウンドにある場合でも、複数の異なるユーザーの場所を追跡するためのより良い方法はありますか?

4

1 に答える 1

4

バックグラウンドタスクを確認する必要があります。

Appleが言うとき、メソッドが戻っsmall amount of time to process location dataた後の処理時間の取得に実際に依存するべきではありません。locationManager:didUpdateToLocation:fromLocation:別のスレッドでHTTPリクエストを非同期で実行していると仮定すると、アプリが一時停止される前にHTTPリクエストを完了するのに十分な時間が与えられていない可能性があります。

UIBackgroundTasksを使用すると、バックグラウンドでの追加の処理時間をオペレーティングシステムに要求できます。HTTPリクエストを作成することはそのようなタスクである可能性があります。制限時間は10分ですが、これだけの時間が保証されるわけではありません。

ロケーションコールバックでは、リクエストの新しいバックグラウンドタスクを定義する必要があります。有効期限ハンドラブロックは、オペレーティングシステムがそれ以上の処理時間を与えることができないと判断した場合、いつでもトリガーされます。

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    // Start your request here
    UIBackgroundTaskIdentifier backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        backgroundTask = UIBackgroundTaskInvalid;
        // Cancel your request here
    }];
}

そして、リクエストが終了したら、タスクが完了したことをアプリケーションに通知する必要があります。

- (void)requestFinished:(id)request {
    [[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
    backgroundTask = UIBackgroundTaskInvalid;
}

この例では、リクエストが完了する前に複数のロケーションコールバックを受け取る可能性があることを考慮していません。その場合は、新しいリクエストを開始する前に、そのリクエストと現在のバックグラウンドタスクをキャンセルするか、リクエストごとに個別のバックグラウンドタスクを作成する必要があります。

別の方法は、ロケーションコールバックメソッドのメインスレッドでHTTPリクエストを同期的に実行することですが、リクエスト中にユーザーがアプリを開いた場合にインターフェースをロックするなど、さまざまな理由でこれを行うのは悪いことです。が走っています。

于 2012-07-04T13:56:14.307 に答える