applicationWillEnterForeground vs. applicationDidBecomeActive, applicationWillResignActive vs. applicationDidEnterBackground

215

¿Cuál es el delegado adecuado para implementar cuando una aplicación está despertando de estar en segundo plano y desea que se prepare para que esté activa?

applicationWillEnterForeground vs applicationDidBecomeActive - ¿Cuál es la diferencia?

¿Cuál es el delegado adecuado para implementar cuando una aplicación se va a suspender y desea prepararla para limpiar y guardar datos?

applicationWillResignActive vs. applicationDidEnterBackground: ¿cuál es la diferencia?

Además, noté que se llama a applicationWillResignActive cuando entra un SMS o una llamada entrante, pero el usuario elige hacer clic en Aceptar y continuar. No quiero que mi aplicación tome ninguna medida en estos casos. Solo quiero que siga ejecutándose sin ninguna limpieza intermedia ya que el usuario no salió de la aplicación. Entonces, creo que tiene más sentido hacer un trabajo de limpieza solo en applicationDidEnterBackground.

Agradecería su aporte sobre las mejores prácticas a seguir para elegir qué delegados implementar para despertarse e irse a dormir, así como considerar eventos como ser interrumpidos por SMS / llamadas.

Gracias

Pablo
fuente

Respuestas:

449

Al despertar, es decir, se relanza una aplicación (ya sea a través de trampolín, cambio de aplicación o URL) applicationWillEnterForeground:. Solo se ejecuta una vez cuando la aplicación está lista para su uso, después de ser puesta en segundo plano, mientras que applicationDidBecomeActive:se puede llamar varias veces después del lanzamiento. Esto lo hace applicationWillEnterForeground:ideal para la configuración que debe ocurrir solo una vez después del relanzamiento.

applicationWillEnterForeground: se llama:

  • cuando se relanza la aplicación
  • antes de applicationDidBecomeActive:

applicationDidBecomeActive: se llama:

  • cuando la aplicación se inicia por primera vez después application:didFinishLaunchingWithOptions:
  • después applicationWillEnterForeground:si no hay URL para manejar.
  • después application:handleOpenURL:se llama.
  • después applicationWillResignActive:si el usuario ignora la interrupción como una llamada telefónica o un SMS.

applicationWillResignActive: se llama:

  • cuando hay una interrupción como una llamada telefónica.
    • si el usuario toma la llamada applicationDidEnterBackground:se llama.
    • si el usuario ignora, se llama a la applicationDidBecomeActive:llamada.
  • cuando se presiona el botón de inicio o el usuario cambia de aplicación.
  • los documentos dicen que deberías
    • pausar tareas en curso
    • desactivar temporizadores
    • pausar un juego
    • reducir las velocidades de fotogramas de OpenGL

applicationDidEnterBackground: se llama:

  • después applicationWillResignActive:
  • los documentos dicen que deberías:
    • liberar recursos compartidos
    • guardar datos de usuario
    • invalidar temporizadores
    • guarde el estado de la aplicación para que pueda restaurarla si la aplicación finaliza.
    • deshabilitar las actualizaciones de la interfaz de usuario
  • tiene 5 segundos para hacer lo que necesita y devolver el método
    • Si no regresa dentro de ~ 5 segundos, la aplicación se cierra.
    • puedes pedir más tiempo con beginBackgroundTaskWithExpirationHandler:

La documentación oficial.

Dan Sandland
fuente
10
Una cosa mas que agregar. Si abre la lista de aplicaciones en segundo plano desde su aplicación (haga doble clic en el botón de inicio) y luego vuelva a ella (elija la vista previa de su aplicación) -applicationWillEnterForeground:, no se llamará solo -applicationDidEnterBackground:(supongamos que iOS no cree que sea un relanzamiento).
kpower
@kpower sí, eso me rompió el cuello ... nunca hubiera pensado que willEnterForeground no será llamado en ese caso ...
TheEye
¿No es así que applicationWillEnterForeground:se llamará cada vez de fondo a primer plano? No puedo encontrar un caso que NO se llame SIN applicationDidBecomeActivedespués.
Desmond DAI
Esto no es exacto. applicationWillResignActive se puede llamar sin applicationDidEnterBackground
MichaelGofron
27

Administrar el ciclo de vida de su aplicación es útil para sus preguntas. Para un concepto rápido, puede ver las Figuras en ese documento. También puede leer el comentario del código generado por el Asistente XCode. Listado de la siguiente manera:

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

Para obtener explicaciones más detalladas, consulte el documento oficial de UIApplicationDelegate

tomjpsun
fuente
El enlace está muerto.
Phlippie Bosman
Revise algunas descripciones y enlaces, 2019 por ahora.
tomjpsun
13

Todavía estaba un poco confundido con la respuesta de Dano, así que hice una pequeña prueba para obtener el flujo de eventos en ciertos escenarios para mi referencia, pero también podría serle útil. Esto es para aplicaciones que NO usan UIApplicationExitsOnSuspenden su info.plist. Esto se realizó en un simulador iOS 8 + confirmado con un dispositivo iOS 7. Disculpe los nombres del controlador de eventos de Xamarin. Ellos son muy similares.

  • Lanzamientos iniciales y posteriores desde un estado de no ejecución:

Lanzamiento terminado

OnActivated

  • Interrupción (llamada telefónica, deslizamiento superior hacia abajo, deslizamiento inferior):
  • El botón de inicio presiona dos veces la lista de aplicaciones inactivas y luego vuelve a seleccionar nuestra aplicación:

OnResignActivation


OnActivated

  • El botón de inicio presiona dos veces la lista de aplicaciones inactivas, selecciona otra aplicación y luego vuelve a iniciar nuestra aplicación:
  • Botón de inicio una sola pulsación, luego reiniciar:
  • Bloquear (botón de encendido / apagado), luego desbloquear:

OnResignActivation

DidEnterBackground


WillEnterForeground

OnActivated

  • Botón de inicio, presione dos veces y finalice nuestra aplicación: (el relanzamiento posterior es el primer caso)

OnResignActivation

DidEnterBackground

DidEnterBackground (¿solo iOS 7?)

Sí, DidEnterBackgroundse llama dos veces en el dispositivo iOS7. En ambas ocasiones, el estado de la aplicación UIA es Fondo. Sin embargo, el simulador de iOS 8 no. Esto necesita pruebas en el dispositivo iOS 8. Actualizaré mi respuesta cuando lo tenga en mis manos, o alguien más podría confirmar.

Rahmi Aksu
fuente
9

applicationWillEnterForeground se llama:

cuando la aplicación se relanza (viene del fondo al primer plano) Este método no se invoca cuando la aplicación se inicia por primera vez, es decir, cuando applicationDidFinishLaunchse llama, sino solo cuando viene del fondo applicationDidBecomeActive

applicationDidBecomeActive se llama

cuando la aplicación se inicia por primera vez después didFinishLaunching después applicationWillEnterForegroundsi no hay una URL para manejar. después application:handleOpenURL:se llama. después applicationWillResignActivesi el usuario ignora la interrupción como una llamada telefónica o un SMS. después de la desaparición de alertView en cualquier lugar de la aplicación

Kareem Waheed
fuente
¿Sabe por casualidad si esto se cambió a partir de iOS 7? Recuerdo (podría estar equivocado) hacer cosas (iOS 5/6) en applicationWillEnterForeground y hacer que se ejecutara cuando la aplicación se lanzó por primera vez. A partir de ahora, en 7.1 / 8, tiene razón applicationWillEnterForeground no recibe una llamada en el lanzamiento.
Jinyoung Kim
7

Se llama a applicationWillResignActive cuando el sistema solicita permisos. (en iOS 10). En caso de que alguien tenga el mismo problema que yo ...

Anson Yao
fuente
¿Alguna idea de qué método se llama después del permiso pop despedir? Tengo este problema stackoverflow.com/questions/26059927/…
Suresh Durishetti
5

En iOS 8+ hay una diferencia sutil pero importante para atender llamadas telefónicas.

En iOS 7, si el usuario atiende una llamada telefónica, se llama a applicationWillResignActive: y applicationDidEnterBackground: Pero en iOS 8+ solo se llama a applicationWillResignActive:.

Qiulang
fuente
1

Para iOS 13+ se ejecutarán los siguientes métodos:

- (void)sceneWillEnterForeground:(UIScene *)scene
- (void)sceneDidBecomeActive:(UIScene *)scene
usuario2994130
fuente