applicationWillEnterForeground vs. applicationDidBecomeActive, applicationWillResignActive vs. applicationDidEnterBackground

¿Cuál es el delegado apropiado para implementar cuando una aplicación está despertando de estar en segundo plano y quieres que esté preparada 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 dormir y desea prepararla para limpiar y guardar datos?

applicationWillResignActive vs. applicationDidEnterBackground – ¿Cuál es la diferencia?

Además, me he dado cuenta de 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 funcionando sin ninguna limpieza intermedia ya que el usuario no salió de la aplicación. Entonces, creo que tiene más sentido hacer el trabajo de limpieza solo en applicationDidEnterBackground.

Agradecería su opinión sobre las mejores prácticas para seguir eligiendo qué delegates implementar para despertar y dormir, así como considerar eventos como ser interrumpido por SMS / llamadas.

Gracias

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

applicationWillEnterForeground: se llama:

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

applicationDidBecomeActive: se llama:

  • cuando la aplicación se lanza por primera vez después de la application:didFinishLaunchingWithOptions:
  • después de applicationWillEnterForeground: si no hay una URL para manejar.
  • después de la application:handleOpenURL: se llama.
  • después de la 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 la llamada applicationDidBecomeActive: se llama.
  • cuando se presiona el botón de inicio o el usuario cambia aplicaciones.
  • docs dicen que deberías
    • pausar las tareas en curso
    • desactivar temporizadores
    • pausa un juego
    • reducir las tasas de cuadros de OpenGL

applicationDidEnterBackground: se llama:

  • después de la applicationWillResignActive:
  • docs 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.
    • desactivar las actualizaciones de UI
  • tienes 5 segundos para hacer lo que necesites y devolver el método
    • si no regresas dentro de ~ 5 segundos, la aplicación se termina.
    • puede solicitar más tiempo con beginBackgroundTaskWithExpirationHandler:

La documentación oficial.

Este documento de Apple es útil para sus preguntas. Para un concepto rápido, puede ver la Figura 3-1 en ese documento. También puede leer el comentario del código generado por el Asistente de XCode. Enumerado 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 restre 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:. */ } 

En el código anterior, solo el lanzamiento de la aplicación tiene la oportunidad de decir SÍ o NO, otros son solo notificaciones. En otras palabras, no tiene forma de obligar a los usuarios a descuidar la llamada entrante o los SMS mediante el listado de códigos anterior. No sé si hay alguna otra solución.

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 UIApplicationExitsOnSuspend en su info.plist. Esto se realizó en un simulador de iOS 8 + confirmado con el dispositivo iOS 7. Disculpe los nombres del manejador de eventos de Xamarin. Ellos son muy similares.

  • Inicial y todos los lanzamientos posteriores desde un estado no en ejecución:

FinishedLaunching

Activado

  • Interrupción (llamada telefónica, deslizamiento hacia arriba, deslizamiento hacia abajo):
  • El botón de inicio hace doble clic en la lista de aplicaciones inactivas, luego vuelve a seleccionar nuestra aplicación:

OnResignActivation


Activado

  • El botón de inicio hace doble clic en la lista de aplicaciones inactivas, selecciona otra aplicación y luego reinicia nuestra aplicación:
  • Botón de inicio presiona una sola vez, luego reinicia:
  • Bloquear (botón de encendido / apagado), luego desbloquear:

OnResignActivation

DidEnterBackground


WillEnterForeground

Activado

  • El botón Inicio presiona dos veces y finaliza nuestra aplicación: (el relanzamiento posterior es el primer caso)

OnResignActivation

DidEnterBackground

DidEnterBackground (¿iOS 7 solamente?)

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

applicationWillEnterForeground se llama:

cuando se relanza la aplicación (viene de fondo a primer plano) Este método no se invoca cuando la aplicación se inicia por primera vez, es decir, cuando se llama a applicationDidFinishLaunch pero solo cuando proviene de background applicationDidBecomeActive

Se llama a applicationDidBecomeActive

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

En iOS 8+ hay una diferencia sutil pero importante para tomar una llamada telefónica.

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

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