web-dev-qa-db-ja.com

applicationWillEnterForeground対applicationDidBecomeActive、applicationWillResignActive対applicationDidEnterBackground

アプリケーションがバックグラウンドで起動しているときにアクティブにする準備をしたいときに実装する適切なデリゲートはどれですか?

applicationWillEnterForeground vs applicationDidBecomeActive-違いは何ですか?

アプリケーションがスリープ状態になり、データをクリーンアップして保存する準備をするときに実装する適切なデリゲートはどれですか?

applicationWillResignActiveとapplicationDidEnterBackground-違いは何ですか?

また、着信SMSまたは通話が着信したが、ユーザーがOkをクリックして続行することを選択したときにapplicationWillResignActiveが呼び出されることに気付きました。これらのケースでは、アプリにアクションを実行させたくありません。ユーザーがアプリを終了しなかったため、中間のクリーンアップなしで実行し続けたいだけです。したがって、applicationDidEnterBackgroundだけでクリーンアップ作業を行う方が理にかなっていると思います。

起床してスリープ状態にするためにどのデリゲートを実装するかを選択し、SMS /通話によって中断されるなどのイベントを検討する際に従うベストプラクティスについてのご意見をお待ちしています。

ありがとう

205
Paul

スリープ解除、つまりアプリを再起動すると(スプリングボード、アプリの切り替え、またはURLのいずれかを介して)applicationWillEnterForeground:が呼び出されます。バックグラウンドに配置された後、アプリが使用可能になったときに1回だけ実行されますが、applicationDidBecomeActive:は起動後に複数回呼び出される場合があります。これにより、applicationWillEnterForeground:は、再起動後に一度だけ実行する必要があるセットアップに最適です。

applicationWillEnterForeground:が呼び出されます:

  • アプリが再起動されたとき
  • beforeapplicationDidBecomeActive:

applicationDidBecomeActive:が呼び出されます:

  • application:didFinishLaunchingWithOptions:の後にアプリが最初に起動されたとき
  • afterapplicationWillEnterForeground:処理するURLがない場合。
  • application:handleOpenURL:が呼び出された後。
  • afterapplicationWillResignActive:ユーザーが電話やSMSなどの割り込みを無視した場合。

applicationWillResignActive:が呼び出されます:

  • 電話のような中断があるとき。
    • ユーザーが電話をとる場合applicationDidEnterBackground:が呼び出されます。
    • ユーザーが呼び出しを無視する場合applicationDidBecomeActive:が呼び出されます。
  • ホームボタンが押されたとき、またはユーザーがアプリを切り替えたとき。
  • ドキュメントはあなたがすべきだと言う
    • 進行中のタスクを一時停止する
    • タイマーを無効にする
    • ゲームを一時停止する
    • openGLフレームレートを下げる

applicationDidEnterBackground:が呼び出されます:

  • applicationWillResignActive:
  • ドキュメントはあなたがすべきだと言う:
    • 共有リソースを解放する
    • ユーザーデータを保存する
    • タイマーを無効にする
    • アプリが終了した場合に復元できるように、アプリの状態を保存します。
    • uI更新を無効にする
  • 必要な処理を行い、メソッドを返すまでに5秒かかります。
    • 5秒以内に戻らないと、アプリは終了します。
    • beginBackgroundTaskWithExpirationHandler:でさらに時間を要求できます

公式ドキュメント。

426
Dan Sandland

このApple Document は質問に役立ちます。簡単な概念については、そのドキュメントの図2-3を参照してください。 XCodeウィザードによって生成されたコードからコメントを読み取ることもできます。次のようにリストされます。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    /*
     Sent when the application is about to move from active to inactive state. 
     This can occur for certain types of temporary interruptions (such as an 
     incoming phone call or SMS message) or when the user quits the application 
     and it begins the transition to the background state.
     Use this method to pause ongoing tasks, disable timers, and throttle down 
     OpenGL ES frame rates. Games should use this method to pause the game.
     */
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    /*
     Use this method to release shared resources, save user data, invalidate 
     timers, and store enough application state information to restore your 
     application to its current state in case it is terminated later. 
     If your application supports background execution, this method is called 
     instead of applicationWillTerminate: when the user quits.
     */
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    /*
     Called as part of the transition from the background to the active state; 
     here you can undo many of the changes made on entering the background.
     */
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    /*
     Restart any tasks that were paused (or not yet started) while the 
     application was inactive. If the application was previously in the 
     background, optionally refresh the user interface.
     */
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    /*
     Called when the application is about to terminate.
     Save data if appropriate.
     See also applicationDidEnterBackground:.
     */
}

上記のコードでは、アプリケーションlaunchingのみが「はい」または「いいえ」と言う機会があります。他は単なる通知です。つまり、上記のコードでユーザーに着信呼び出しまたはSMSを無視させることはできません。他の回避策があるかどうかわからない。

26
tomjpsun

私はまだDanoの答えと少し混同していたので、参考のために特定のシナリオでイベントのフローを取得するために少しテストを行いましたが、それはあなたにも役立つかもしれません。これは、info.plistでUIApplicationExitsOnSuspendを使用しないアプリ用です。これはiOS 8シミュレーターで実施され、iOS 7デバイスで確認されました。 Xamarinのイベントハンドラー名を言い訳してください。それらは非常に似ています。

  • 実行されていない状態からの初期およびその後のすべての起動:

終了しました

OnActivated

  • 中断(通話、上部スライドダウン、下部スライドアップ):
  • ホームボタンは、非アクティブなアプリのリストを2回押し、アプリを再選択します。

OnResignActivation


OnActivated

  • ホームボタンを押して非アクティブなアプリをダブルクリックし、別のアプリを選択してからアプリを再起動します
  • ホームボタンを1回押してから再起動します。
  • ロック(オン/オフボタン)、次にロック解除:

OnResignActivation

DidEnterBackground


WillEnterForeground

OnActivated

  • ホームボタンを2回押してアプリを終了します(その後の再起動が最初のケースです)。

OnResignActivation

DidEnterBackground

DidEnterBackground(iOS 7のみ?)

はい、iOS7デバイスでDidEnterBackgroundが2回呼び出されます。両方のUIApplication状態はバックグラウンドです。ただし、iOS 8シミュレーターはサポートしていません。これには、iOS 8デバイスでのテストが必要です。答えを更新するか、他の誰かが確認できます。

13
Rahmi Aksu

applicationWillEnterForegroundが呼び出されます:

アプリが再起動されたとき(バックグラウンドからフォアグラウンドへ)このメソッドは、アプリが初めて起動したとき、つまりapplicationDidFinishLaunchが呼び出されたときに呼び出されますが、バックグラウンドから来たときapplicationDidBecomeActive

applicationDidBecomeActiveが呼び出されます

処理するURLがない場合、didFinishLaunchingの後にapplicationWillEnterForegroundの後にアプリが最初に起動されたとき。 application:handleOpenURL:が呼び出された後。 applicationWillResignActiveの後、ユーザーが電話やSMSなどの割り込みを無視した場合。アプリケーションからどこでもalertViewが消えた後

9
Kareem Waheed

applicationWillResignActiveは、システムが許可を求めているときに呼び出されます。 (iOS 10)。誰かが私と同じトラブルに遭遇した場合に備えて...

7
Anson Yao

IOS 8以降では、電話を受ける際に微妙ですが重要な違いがあります。

IOS 7では、ユーザーが電話をかけるとapplicationWillResignActive:とapplicationDidEnterBackground:の両方が呼び出されます。ただし、iOS 8以降ではapplicationWillResignActive:のみが呼び出されます。

5
Qiulang