applicationWillEnterForeground vs. applicationDidBecomeActive, applicationWillResignActive vs. applicationDidEnterBackground


215

Qual è il delegato appropriato da implementare quando un'applicazione si sta svegliando dallo sfondo e vuoi che sia predisposta per essere attiva?

applicationWillEnterForeground vs applicationDidBecomeActive - Qual è la differenza?

Qual è il delegato appropriato da implementare quando un'applicazione va in sospensione e si desidera prepararla per la pulizia e il salvataggio dei dati?

applicationWillResignActive vs. applicationDidEnterBackground - Qual è la differenza?

Inoltre, ho notato che applicationWillResignActive viene chiamato quando arriva un SMS o una chiamata in arrivo, ma l'utente sceglie di fare clic su OK e continuare. Non voglio che la mia app esegua alcuna azione in questi casi. Voglio solo che continui a funzionare senza alcuna pulizia intermedia poiché l'utente non è uscito dall'app. Quindi, penso che abbia più senso fare il lavoro di pulizia solo in applicationDidEnterBackground.

Gradirei il tuo contributo alle migliori pratiche da seguire per scegliere quali delegati implementare per svegliarsi e andare a dormire, oltre a considerare eventi come essere interrotti da SMS / chiamate.

Grazie

Risposte:


449

Al risveglio applicationWillEnterForeground:viene chiamato il riavvio di un'app (tramite trampolino, cambio di app o URL) . Viene eseguito solo una volta quando l'app è pronta per l'uso, dopo essere stata messa in background, mentre applicationDidBecomeActive:può essere chiamata più volte dopo l'avvio. Questo è l' applicationWillEnterForeground:ideale per l'installazione che deve avvenire una sola volta dopo il riavvio.

applicationWillEnterForeground: è chiamato:

  • quando l'app viene riavviata
  • prima applicationDidBecomeActive:

applicationDidBecomeActive: è chiamato:

  • quando l'app viene avviata dopo la prima volta application:didFinishLaunchingWithOptions:
  • dopo applicationWillEnterForeground:se non c'è un URL da gestire.
  • dopo application:handleOpenURL:viene chiamato.
  • dopo applicationWillResignActive:se l'utente ignora l'interruzione come una telefonata o un SMS.

applicationWillResignActive: è chiamato:

  • quando c'è un'interruzione come una telefonata.
    • se l'utente prende la chiamata applicationDidEnterBackground:viene chiamato.
    • se l'utente ignora la chiamata applicationDidBecomeActive:viene chiamata.
  • quando viene premuto il pulsante Home o l'utente cambia app.
  • i documenti dicono che dovresti
    • mettere in pausa le attività in corso
    • disabilita i timer
    • mettere in pausa una partita
    • ridurre i frame rate OpenGL

applicationDidEnterBackground: è chiamato:

  • dopo applicationWillResignActive:
  • i documenti dicono che dovresti:
    • rilasciare risorse condivise
    • salva i dati dell'utente
    • timer non validi
    • salva lo stato dell'app in modo da poterlo ripristinare se l'app viene terminata.
    • disabilita gli aggiornamenti dell'interfaccia utente
  • hai 5 secondi per fare quello che ti serve e restituire il metodo
    • se non ritorni entro ~ 5 secondi l'app viene chiusa.
    • puoi chiedere più tempo con beginBackgroundTaskWithExpirationHandler:

La documentazione ufficiale


10
Un'altra cosa da aggiungere. Se apri l'elenco delle app in background dalla tua app (fai doppio clic sul pulsante Home) e poi ritorni ad esso (scegli l'anteprima della tua app) - -applicationWillEnterForeground:non verrà chiamato, solo -applicationDidEnterBackground:(supponi che iOS non pensi che sia un riavvio).
kpower,

@kpower sì, che mi ha appena rotto il collo ... non avrei mai pensato che WillEnterForeground non si sarebbe chiamato in quel caso ...
TheEye

Non applicationWillEnterForeground:sarà chiamato ogni volta dallo sfondo al primo piano ?! Non riesco a trovare un caso che NON viene chiamato SENZA in applicationDidBecomeActiveseguito.
Desmond DAI

Questo non è accurato applicationWillResignActive può essere chiamato senza applicationDidEnterBackground
MichaelGofron

27

La gestione del ciclo di vita della tua app è utile per le tue domande. Per una rapida idea, puoi vedere le figure in quel documento. Puoi anche leggere il commento dal codice generato dalla procedura guidata XCode. Elencato come segue:

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

Per spiegazioni più dettagliate, fare riferimento al documento ufficiale di UIApplicationDelegate


Il link è morto.
Phlippie Bosman,

Rivedi alcune descrizioni e collegamenti, per il 2019 per ora.
tomjpsun,

13

Ero ancora un po 'confuso con la risposta di Dano, quindi ho fatto un piccolo test per ottenere il flusso di eventi in determinati scenari per il mio riferimento, ma potrebbe essere utile anche a te. Questo è per le app che NON usano UIApplicationExitsOnSuspendnella loro info.plist. Questo è stato condotto su un simulatore iOS 8 + confermato con dispositivo iOS 7. Scusa i nomi dei gestori di eventi di Xamarin. Sono molto simili.

  • Avvio iniziale e tutti i successivi da uno stato non in esecuzione:

FinishedLaunching

OnActivated

  • Interruzione (telefonata, slide-down in alto, slide-in in basso):
  • Pulsante Home: premi due volte l'elenco delle app inattive, quindi seleziona nuovamente la nostra app:

OnResignActivation


OnActivated

  • Pulsante Home premi due volte per elencare le app inattive, selezionare un'altra app, quindi riavviare la nostra app:
  • Tasto Home: premi una volta, quindi riavvia:
  • Blocca (pulsante on / off), quindi sblocca:

OnResignActivation

DidEnterBackground


WillEnterForeground

OnActivated

  • Premi due volte il tasto Home e termina la nostra app: (il successivo riavvio è il primo caso)

OnResignActivation

DidEnterBackground

DidEnterBackground (solo iOS 7?)

Sì, DidEnterBackgroundviene chiamato due volte sul dispositivo iOS7. Entrambe le volte lo stato di UIApplication è Background. Tuttavia, il simulatore iOS 8 no. Ciò richiede test sul dispositivo iOS 8. Aggiornerò la mia risposta quando ci metto la mano, o qualcun altro potrebbe confermare.


9

applicationWillEnterForeground è chiamato:

quando l'app viene riavviata (passa dallo sfondo al primo piano) Questo metodo non viene invocato quando l'app viene avviata per la prima volta, ovvero quando applicationDidFinishLaunchviene chiamato, ma solo quando viene dallo sfondo applicationDidBecomeActive

applicationDidBecomeActive è chiamato

quando l'app viene avviata per la prima volta dopo didFinishLaunching dopo applicationWillEnterForegroundse non c'è un URL da gestire. dopo application:handleOpenURL:viene chiamato. dopo applicationWillResignActivese l'utente ignora l'interruzione come una telefonata o un SMS. dopo la scomparsa di alertView ovunque dall'applicazione


Sai per caso se questo è stato modificato a partire da iOS 7? Ricordo (potrei sbagliarmi) di fare cose (iOS 5/6) in applicationWillEnterForeground e di averlo eseguito al primo avvio dell'app. A partire da ora, in 7.1 / 8, hai ragione l'applicazioneWillEnterForeground non viene chiamato all'avvio.
Jinyoung Kim,


5

In iOS 8+ c'è una differenza sottile ma importante per rispondere alle chiamate.

In iOS 7 se l'utente prende la telefonata vengono chiamate sia applicationWillResignActive: sia applicationDidEnterBackground:. Ma in iOS 8+ solo applicationWillResignActive: viene chiamata.


1

Per iOS 13+ verranno eseguiti i seguenti metodi:

- (void)sceneWillEnterForeground:(UIScene *)scene
- (void)sceneDidBecomeActive:(UIScene *)scene
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.