終了/中断されたときの重要な変更場所APIの動作?


108

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

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

私の理解では、アプリの終了は、(あなたが呼び出していない場合、私が想定した場合ということですので、stopMonitoringSignificantLocationChangesをからapplicationWillTerminate)あなたが覚めてしまいますUIApplicationLaunchOptionsLocationKeyのにパラメータdidFinishLaunchingWithOptions:アプリケーション。その時点でCLLocationManagerを作成し、startMonitoringSignificantLocationChangesを呼び出して、バックグラウンドでの位置処理を限られた時間実行します。だから私はこのビットで大丈夫です。

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

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

終了後、(場所の変更により)アプリが起動された場合にのみこの通話を受信することを提案します。

しかし、上の段落の大幅な変更サービスにおける位置認識プログラミングガイドが言うには、以下のい:

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

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

  • UIApplicationDelegateは、私がバックグラウンド状態にサスペンド状態から再開していますことを私に言って、コールバックを取得しますか?
  • (アプリが中断されたときにフリーズドライされた)ロケーションマネージャーは、locationManager :didUpdateToLocation:fromLocationコールバックの受信を開始しますか?
  • アプリケーションの状態をチェックし、バックグラウンドモードの場合に最小限の処理を行うコードをdidUpdateToLocationメッセージに実装するだけでよいですか?

これを書いている最中、私は自分の質問に答えたばかりかもしれないと思いますが、これについての私の理解をより知識のある誰かに確認してもらうと素晴らしいでしょう。

回答:


80

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

つまり、一時停止されたアプリがウェイクアップされ、アプリデリゲートでコールバックを受け取らず、既存のCLLocationManagerDelegateを通じて位置情報の更新を受け取ります。applicationStateを確認することで、バックグラウンドで実行していることを検出でき、一時停止状態からウェイクしてロケーション処理を実行している場合に限られた作業を実行できます。

[UIApplication sharedApplication].applicationState == UIApplicationStateBackground

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

前の答えのNBポイント6は正しくありません。フリーズドライサスペンドされたアプリは、サスペンド状態からウェイクアップされたときにCLLocationManagerDelegateコールバックを受け取ります。


1
人々を混乱させないために私の答えで#6を取り消しました。
アーロン

皮肉なことに、私は重要な変化のために開発するときにも同じ混乱を感じました。アプリが閉じられた場合、どうなるかまだ疑問があります。UIApplicationDelegateコールバックは発生しませんか?アプリを起動する正しい方法です。ロケーションマネージャーがまだ起動していない場合、バックグラウンドで通知を取得するにはどうすればよいですか?(さらに多くのR&Dの時間)
darshansonde 2012

サンプルアプリをありがとう、それは私にとって非常に役に立ちました。質問があります。重要なサービスではなく、標準の位置情報サービスをバックグラウンドで使用していた場合、その場合、終了後にアプリも再起動されますか?私はここでこの質問を詳細に尋ねました。私を明るくしてくれたらうれしいです:] stackoverflow.com/questions/12239967/…–
aslisabanci


アプリが終了するまでにかかった時間を知っていますか?そして、代わりにappDelegateコールバックを取得しますか?(30分ですか?2時間?5時間?)これを尋ねる理由は、監視する領域を設定したためです。アプリの起動を何度も試しましたが、アプリを再起動する必要があったのは1回だけです。もう1回はdidExitRegionコールバックですがstartLocationUpdates、アプリの起動を介していないため、そこからはコールバックできませんでした...
Honey

25

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

  1. アプリケーションは初めて実行され、startMonitoringSignificantLocationChangesに登録し、コールバック関数を提供します。アプリケーションの実行中は、大きな変更を受け取るたびにそのコールバックを呼び出します。
  2. アプリケーションがバックグラウンドに置かれると、UIApplicationはapplicationWillResignActiveを受け取り、その後にapplicationDidEnterBackgroundを受け取ります
  3. アプリケーションがバックグラウンドで一時停止されているときに強制終了された場合、通知されません。ただし、アプリケーションが実行中に強制終了された場合(私の知る限り、フォアグラウンドまたはバックグラウンド)、applicationWillTerminateで瞬間が表示されます。この関数から追加のバックグラウンドタイムを要求することはできません。
  4. バックグラウンドで強制終了されているにもかかわらず、OSはアプリケーションを再起動します。アプリケーションが変更のためにOSによって単に起動された場合、アプリケーションdidFinishLaunchingWithOptionsへの呼び出しを取得します

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])

    バックグラウンドの場所の変更から戻ってきたかどうかを判断するのに役立ちます。

  5. 代わりに、現在バックグラウンドで実行していて、ユーザーがアプリを手動で再起動すると、applicationWillEnterForegroundに続いてapplicationDidBecomeActiveが返されます
  6. どのように発生したかに関係なく、アプリケーションが再起動されたとき(バックグラウンドタスクの結果としてアプリケーションがまだバックグラウンドで実行されていて、そのタスクが変更の監視を開始していた場合を除く)、コールバックがnoであるため、再度startMonitoringSignificantLocationChangesを明示的に通知する必要があります。 「凍結乾燥」後は長く付着します。そして、はい、一時停止状態から戻ったときに、ある種のロケーションハンドラーを再アタッチしたら、didUpdateToLocationにコードを実装する必要があります。

これは、現在コード開発で行っていることです。前に述べたように、私はこれをデバイスでテストする準備がまだ整っていないので、すべてを正しく解釈したかどうかはわかりません。そのため、コメンターは自由に修正してください(トピック)。

ああ、そして不運のストロークで、私のやりたいことを実行するアプリをリリースすると、私は泣くかもしれません:)

幸運を!


1
@ Tegeril +1答えてくれてありがとう。私はこれについてコオロギを聞き始めていました。:)中断状態から開始されたアプリがstartMonitoringSignificantLocationChangesを再度呼び出す必要があることに驚いています。これが説明されているドコへのリンクはありますか?一時停止状態から読み込まれると、アプリが一時停止されたときと同じようにすべてのオブジェクトがインスタンス化されることを理解していました。したがって、重要な変更リクエストが有効になることを期待します。
RedBlueThing 2010

あなたはこれについて話しているのでしょうか?「再起動しても、ロケーションマネージャーオブジェクトを設定し、このメソッドを呼び出してロケーションイベントの受信を継続する必要があります」これは、(ロケーションイベントによって)アプリが終了状態から起動した場合を指していると思います。これは基本的に私の質問の根本です、「停止されたケースはどうなりますか?」
RedBlueThing 2010

DevフォーラムのMorgan Graingerは、次のように提案しています。「アプリケーションの起動時にCLLocationManagerを作成し、デリゲートを設定し、startMonitoringSignificantLocationChangesを呼び出す必要があります。そうしないと、コアロケーションに更新を配信する場所がなくなります。」終了または一時停止の状態に関係なく、アプリケーションを再起動するコンテキストで。「startMonitoringSignificantLocationChangesの後にアプリが再起動されましたが、今は何ですか?」
アーロン

これは、そのフォーラムの投稿の文脈でもなお曖昧である可能性があることに同意します(ポスターは背景からの覚醒について議論していましたが、モーガンはより一般的なアプリケーションの再起動を使用していました)。重要な変更機能を使用したい場合は、アプリケーションが再起動したときに再度監視するために呼び出す必要があると思います。代わりにバックグラウンドタスクを起動して、標準の位置情報サービスとGPS機能で更新する場合は、別のオプションです。ただし、再起動するために、大幅な変更を行うたびに再登録する必要があるとは思いません。
アーロン

1
これから決定的なことが出てきてうれしいです。将来私を助けてくれるでしょう:)
アーロン

1

場所の変更の結果としてアプリケーションが一時停止状態から呼び出された場合、アプリケーションはバックグラウンド状態で起動します。

すべてのオブジェクトがライブになり、既存のデリゲートで位置の更新を受け取ります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.