applicationWillEnterForeground vs. applicationDidBecomeActive, applicationWillResignActive vs. applicationDidEnterBackground

215

Quel est le délégué approprié à implémenter lorsqu'une application sort de l'arrière-plan et que vous souhaitez qu'elle soit préparée pour être active?

applicationWillEnterForeground vs applicationDidBecomeActive - Quelle est la différence?

Quel est le délégué approprié à implémenter lorsqu'une application va se mettre en veille et que vous souhaitez la préparer au nettoyage et à l'enregistrement des données?

applicationWillResignActive vs. applicationDidEnterBackground - Quelle est la différence?

De plus, j'ai remarqué que applicationWillResignActive est appelé lorsqu'un SMS ou un appel entrant arrive, mais l'utilisateur choisit de cliquer sur OK et de continuer. Je ne souhaite pas que mon application prenne des mesures dans ces cas. Je veux juste qu'il continue à fonctionner sans aucun nettoyage intermédiaire car l'utilisateur n'a pas quitté l'application. Donc, je pense qu'il est plus logique de faire un travail de nettoyage uniquement dans applicationDidEnterBackground.

J'apprécierais votre contribution sur les meilleures pratiques à suivre pour choisir les délégués à mettre en œuvre pour se réveiller et s'endormir, ainsi que pour prendre en compte des événements comme être interrompu par SMS / appels.

Merci

Paul
la source

Réponses:

449

Au réveil, c'est-à-dire que la relance d'une application (via un tremplin, un changement d'application ou une URL) applicationWillEnterForeground:est appelée. Il n'est exécuté qu'une seule fois lorsque l'application est prête à l'emploi, après avoir été mise en arrière-plan, tandis qu'elle applicationDidBecomeActive:peut être appelée plusieurs fois après le lancement. Cela rend applicationWillEnterForeground:idéal pour la configuration qui doit se produire une seule fois après la relance.

applicationWillEnterForeground: est appelé:

  • lorsque l'application est relancée
  • avant applicationDidBecomeActive:

applicationDidBecomeActive: est appelé:

  • lorsque l'application est lancée pour la première fois après application:didFinishLaunchingWithOptions:
  • après applicationWillEnterForeground:s'il n'y a pas d'URL à gérer.
  • après application:handleOpenURL:est appelé.
  • après applicationWillResignActive:si l'utilisateur ignore l'interruption comme un appel téléphonique ou un SMS.

applicationWillResignActive: est appelé:

  • lorsqu'il y a une interruption comme un appel téléphonique.
    • si l'utilisateur prend l'appel applicationDidEnterBackground:est appelé.
    • si l'utilisateur ignore l'appel applicationDidBecomeActive:est appelé.
  • lorsque le bouton d'accueil est enfoncé ou que l'utilisateur change d'application.
  • les documents disent que vous devriez
    • suspendre les tâches en cours
    • désactiver les minuteurs
    • mettre un jeu en pause
    • réduire les taux de trame OpenGL

applicationDidEnterBackground: est appelé:

  • après applicationWillResignActive:
  • les documents disent que vous devriez:
    • libérer des ressources partagées
    • enregistrer les données utilisateur
    • invalider les minuteries
    • enregistrer l'état de l'application afin de pouvoir le restaurer si l'application est fermée.
    • désactiver les mises à jour de l'interface utilisateur
  • vous avez 5 secondes pour faire ce dont vous avez besoin et renvoyer la méthode
    • si vous ne revenez pas dans les ~ 5 secondes, l'application est fermée.
    • vous pouvez demander plus de temps avec beginBackgroundTaskWithExpirationHandler:

La documentation officielle.

Dan Sandland
la source
10
Une autre chose à ajouter. Si vous ouvrez la liste des applications d'arrière-plan à partir de votre application (double-cliquez sur le bouton d'accueil), puis y retournez (choisissez l'aperçu de votre application) - -applicationWillEnterForeground:ne sera pas appelé uniquement -applicationDidEnterBackground:(supposons, iOS ne pense pas que c'est une relance).
kpower
@kpower oui, ça vient de me casser le cou ... je n'aurais jamais pensé que willEnterForeground ne serait pas appelé dans ce cas ...
TheEye
N'est-ce pas ce qui applicationWillEnterForeground:sera appelé à chaque fois de l'arrière-plan au premier plan?! Je ne trouve pas de cas qui ne soit PAS appelé SANS applicationDidBecomeActivepar la suite.
Desmond DAI
Ce n'est pas exact. applicationWillResignActive peut être appelée sans applicationDidEnterBackground
MichaelGofron
27

La gestion du cycle de vie de votre application est utile pour vos questions. Pour un concept rapide, vous pouvez voir les figures dans ce document. Vous pouvez également lire le commentaire à partir du code généré par l'assistant XCode. Listé comme suit:

- (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:.
     */
}

Pour des explications plus détaillées, veuillez vous référer au document officiel pour UIApplicationDelegate

tomjpsun
la source
Le lien est mort.
Phlippie Bosman
Révisez quelques descriptions et liens, 2019 pour l'instant.
tomjpsun
13

J'étais encore un peu confus avec la réponse de Dano, j'ai donc fait un petit test pour obtenir le flux des événements dans certains scénarios pour ma référence, mais cela pourrait aussi vous être utile. C'est pour les applications qui n'utilisent PAS UIApplicationExitsOnSuspenddans leur info.plist. Cela a été effectué sur un simulateur iOS 8 + confirmé avec un appareil iOS 7. Veuillez excuser les noms des gestionnaires d'événements de Xamarin. Ils sont très similaires.

  • Lancements initiaux et ultérieurs à partir d'un état non actif:

Fin du lancement

Activé

  • Interruption (appel téléphonique, liste déroulante supérieure, liste déroulante inférieure):
  • Appuyez deux fois sur le bouton Accueil pour répertorier les applications inactives, puis resélectionnez notre application:

OnResignActivation


Activé

  • Appuyez deux fois sur le bouton Accueil pour répertorier les applications inactives, sélectionner une autre application, puis relancer notre application:
  • Appuyez sur le bouton d'accueil, puis relancez:
  • Verrouiller (bouton marche / arrêt), puis déverrouiller:

OnResignActivation

DidEnterBackground


WillEnterForeground

Activé

  • Appuyez deux fois sur le bouton d'accueil et fermez notre application: (la relance suivante est le premier cas)

OnResignActivation

DidEnterBackground

DidEnterBackground (iOS 7 uniquement?)

Oui, DidEnterBackgroundest appelé deux fois sur l'appareil iOS7. Les deux fois, l'état UIApplication est Arrière-plan. Cependant, le simulateur iOS 8 ne le fait pas. Cela nécessite des tests sur l'appareil iOS 8. Je mettrai à jour ma réponse lorsque j'y mettrai la main, ou quelqu'un d'autre pourrait confirmer.

Rahmi Aksu
la source
9

applicationWillEnterForeground est appelé:

lorsque l'application est relancée (vient de l'arrière-plan au premier plan) Cette méthode n'est pas invoquée lorsque l'application démarre pour la première fois, c'est-à-dire lorsque applicationDidFinishLaunch est appelé , mais seulement quand vient de fond applicationDidBecomeActive

applicationDidBecomeActive est appelé

lorsque l'application est lancée pour la première fois après didFinishLaunching après applicationWillEnterForegrounds'il n'y a pas d'URL à gérer. après application:handleOpenURL:est appelé. après applicationWillResignActivesi l'utilisateur ignore l'interruption comme un appel téléphonique ou un SMS. après la disparition de alertView n'importe où dans l'application

Kareem Waheed
la source
Savez-vous par hasard si cela a été modifié depuis iOS 7? Je me souviens (je pourrais me tromper) avoir fait des choses (iOS 5/6) dans applicationWillEnterForeground et l'avoir exécuté lors du premier lancement de l'application. Pour l'instant, en 7.1 / 8, vous avez raison, applicationWillEnterForeground ne sera pas appelé au lancement.
Jinyoung Kim
7

applicationWillResignActive est appelée lorsque le système demande des autorisations. (dans iOS 10). Juste au cas où quelqu'un rencontrerait le même problème que moi ...

Anson Yao
la source
une idée de quelle méthode s'appeler après la permission pop pop rejeter? J'ai ce problème stackoverflow.com/questions/26059927/…
Suresh Durishetti
5

Dans iOS 8+, il existe une différence subtile mais importante pour prendre un appel téléphonique.

Dans iOS 7, si l'utilisateur prend un appel téléphonique, les deux applicationWillResignActive: et applicationDidEnterBackground: sont appelées. Mais dans iOS 8+, seule l'applicationWillResignActive: est appelée.

Qiulang
la source
1

Pour iOS 13+, les méthodes suivantes seront exécutées:

- (void)sceneWillEnterForeground:(UIScene *)scene
- (void)sceneDidBecomeActive:(UIScene *)scene
user2994130
la source