108

これは、startMonitoringSignificantLocationChangesを使用したアプリの動作を説明するCLLocationManagerドキュメントのセクションです。

このサービスを開始し、その後アプリケーションが終了した場合、新しいイベントが到着すると、システムは自動的にアプリケーションをバックグラウンドで再起動します。このような場合、アプリケーションデリゲートのapplication:didFinishLaunchingWithOptions:メソッドに渡されるオプションディクショナリには、ロケーションイベントが原因でアプリケーションが起動されたことを示すキーUIApplicationLaunchOptionsLocationKeyが含まれています。再起動時に、ロケーションマネージャオブジェクトを設定し、このメソッドを呼び出してロケーションイベントの受信を継続する必要があります。位置情報サービスを再開すると、現在のイベントがすぐに代理人に配信されます。さらに、ロケーションマネージャオブジェクトのロケーションプロパティには、ロケーションサービスを開始する前でも、最新のロケーションオブジェクトが入力されます。

したがって、私の理解では、アプリが終了した場合(そして、applicationWillTerminateからstopMonitoringSignificantLocationChangesを呼び出さなかった場合application :didFinishLaunchingWithOptionsへのUIApplicationLaunchOptionsLocationKeyパラメーターでウェイクアップされます。その時点で、CLLocationManagerを作成し、 startMonitoringSignificantLocationChangesを呼び出して、限られた時間だけバックグラウンドロケーション処理を実行します。だから私はこのビットで大丈夫です。

前の段落では、アプリが終了したときに何が起こるかについてのみ説明しており、アプリケーションが一時停止されたときに何をするかについては示唆していません。didFinishLaunchingWithOptionsのドキュメントには次のように書かれています。

アプリケーションはバックグラウンドで位置の更新を追跡し、パージされ、再起動されました。この場合、ディクショナリには、新しいロケーションイベントが原因でアプリケーションが再起動されたことを示すキーが含まれています。

この呼び出しは、終了後にアプリが起動されたとき(場所が変更されたため)にのみ受信されることを提案します。

ただし、ロケーション認識プログラミングガイドの重要な変更サービスに関する段落には、次のように記載されています。

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

これは、アプリが一時停止されている場合に位置データで目覚めていることを示していますが、どのように目覚めているのかについては言及していません。

  • UIApplicationDelegateは、一時停止状態からバックグラウンド状態に再開していることを通知するコールバックを受け取りますか
  • ロケーションマネージャー(アプリが一時停止されたときにフリーズドライされた)は、locationManager:didUpdateToLocation:fromLocationコールバックの受信を開始しますか?
  • アプリケーションの状態をチェックし、バックグラウンドモードの場合は最小限の処理を実行するdidUpdateToLocationメッセージにコードを実装する必要がありますか?

これを書いている過程で、私は自分の質問に答えたばかりかもしれませんが、これについての私の理解をもっと知識のある人に確認してもらうのは素晴らしいことです。

4

4 に答える 4

81

この質問をして以来、かなりのテストを行い(主に自宅と職場の間の電車の中で)、中断されたアプリの動作が質問の最後で疑ったとおりであることを確認しました.

つまり、中断されたアプリが起動され、アプリのデリゲートでコールバックを受信せず、代わりに既存のCLLocationManagerDelegateを介して位置情報の更新を受信します。applicationStateをチェックすることでバックグラウンドで実行されていることを検出でき、位置情報処理を行うために一時停止状態から復帰した場合に限定された作業を行うことができます。

[UIApplication sharedApplication].applicationState == UIApplicationStateBackground

この結論に達した場所のテスト ハーネスをダウンロードして試してみてください。これは非常にシンプルなアプリで、UI を介して大幅な変更と GPS 変更 API を有効にし、返されたすべての応答をログに記録できます。

: 前の回答のポイント 6 は正しくありません。フリーズドライの中断されたアプリは、中断状態から復帰したときにCLLocationManagerDelegateコールバックを受け取ります。

于 2010-08-14T14:18:25.717 に答える
25

私の理解は次のとおりです (私はこの API に依存するアプリケーションを作成中ですが、テストを開始するのに十分なほどこのコンポーネントを完成させていません):

  1. アプリケーションが初めて実行され、startMonitoringSignificantLocationChangesに登録し、コールバック関数を提供します。アプリケーションの実行中、重要な変更を受け取るたびに、そのコールバックが呼び出されます。

  2. アプリケーションがバックグラウンドに置かれた場合、UIApplication は applicationWillResignActive を受け取り続いてapplicationDidEnterBackgroundを受け取ります。

  3. 一時停止中にアプリケーションが強制終了された場合、通知はありません。ただし、実行中にアプリケーションが強制終了された場合 (私の知る限りフォアグラウンドまたはバックグラウンド)、 applicationWillTerminateで少し時間がかかります。この関数から余分なバックグラウンド時間を要求することはできません。

  4. バックグラウンドで強制終了されたにもかかわらず、OS はアプリケーションを再起動します。アプリケーションが単に変更のために OS によって起動された場合、アプリケーション didFinishLaunchingWithOptionsへの呼び出しが発生します。

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])
    

バックグラウンドでの場所の変更から戻ってきたかどうかを判断するのに役立ちます。5. 代わりに、現在バックグラウンドで実行されていて、アプリがユーザーによって手動で再起動された場合、applicationWillEnterForegroundに続いてapplicationDidBecomeActiveを受け取ります。6.それがどのように発生したかに関係なく、アプリケーションが再起動されたときに (バックグラウンド タスクの結果としてバックグラウンドでまだ実行されていて、そのタスクが変更の監視を開始した場合を除く)、startMonitoringSignificantLocationChangesを明示的に指示する必要があります。「凍結乾燥」の後、コールバックがアタッチされなくなるためです。はい、サスペンド状態から戻ったときに何らかのロケーション ハンドラーを再アタッチしたら、didUpdateToLocation にコードを実装するだけで済みます。

これが、現在コード開発で行っていることです。前に述べたように、デバイスでこれをテストする準備ができていないので、すべてを正しく解釈したかどうかはわかりません。トピック)。

ああ、もし運が悪かったら、私がやりたいことをするアプリをあなたがリリースしたら、私は泣くかもしれません :)

幸運を!

于 2010-08-10T04:54:28.640 に答える