ChatGPT解决这个技术问题 Extra ChatGPT

applicationWillEnterForeground vs. applicationDidBecomeActive, applicationWillResignActive vs. applicationDidEnterBackground

Which is the proper delegate to implement when an application is waking up from being in the background and you want it to prep it to be active?

applicationWillEnterForeground vs applicationDidBecomeActive -- What's the difference?

Which is the proper delegate to implement for when an application is going to sleep and you want to prep it to cleanup and save data?

applicationWillResignActive vs. applicationDidEnterBackground -- What's the difference?

Also, I've noticed that applicationWillResignActive gets called when an incoming SMS or call comes in but the user chooses to click Ok and continue. I don't want my app to take any action in these cases. I just want it to keep running without any intermediate cleanup since the user didn't exit the app. So, I would think it makes more sense to do cleanup work just in applicationDidEnterBackground.

I would appreciate your input on best practices to follow on choosing which delegates to implement for waking up and going to sleep as well as considering events like being interrupted by SMS/calls.

Thanks


C
Cœur

When waking up i.e. relaunching an app (either through springboard, app switching or URL) applicationWillEnterForeground: is called. It is only executed once when the app becomes ready for use, after being put into the background, while applicationDidBecomeActive: may be called multiple times after launch. This makes applicationWillEnterForeground: ideal for setup that needs to occur just once after relaunch.

applicationWillEnterForeground: is called:

when app is relaunched

before applicationDidBecomeActive:

applicationDidBecomeActive: is called:

when app is first launched after application:didFinishLaunchingWithOptions:

after applicationWillEnterForeground: if there's no URL to handle.

after application:handleOpenURL: is called.

after applicationWillResignActive: if user ignores interruption like a phone call or SMS.

applicationWillResignActive: is called:

when there is an interruption like a phone call. if user takes call applicationDidEnterBackground: is called. if user ignores call applicationDidBecomeActive: is called.

if user takes call applicationDidEnterBackground: is called.

if user ignores call applicationDidBecomeActive: is called.

when the home button is pressed or user switches apps.

docs say you should pause ongoing tasks disable timers pause a game reduce OpenGL frame rates

pause ongoing tasks

disable timers

pause a game

reduce OpenGL frame rates

applicationDidEnterBackground: is called:

after applicationWillResignActive:

docs say you should: release shared resources save user data invalidate timers save app state so you can restore it if app is terminated. disable UI updates

release shared resources

save user data

invalidate timers

save app state so you can restore it if app is terminated.

disable UI updates

you have 5 seconds to do what you need to and return the method if you don't return within ~5 seconds the app is terminated. you can ask for more time with beginBackgroundTaskWithExpirationHandler:

if you don't return within ~5 seconds the app is terminated.

you can ask for more time with beginBackgroundTaskWithExpirationHandler:

The official documentation.


One more thing to add. If you open background apps list from your app (double-click home button) and then return back to it (choose your app's preview) - -applicationWillEnterForeground: won't be called, only -applicationDidEnterBackground: (suppose, iOS don't think that it's a relaunch).
@kpower yes, that just broke my neck ... never would have thought that willEnterForeground will not be called in that case ...
Isn't it that applicationWillEnterForeground: will be called every time from background to foreground?! I cannot find a case that it is NOT called WITHOUT applicationDidBecomeActive afterwards.
This isn't accurate. applicationWillResignActive can be called without applicationDidEnterBackground
t
tomjpsun

Managing Your App's Life Cycle is helpful to your questions. For quick concept, you can see Figures in that document. You can also read the comment from the code generated by the XCode Wizard. Listed as follows:

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

For more detailed explanations, please refer to official document for UIApplicationDelegate


The link is dead.
Revise some descriptions and links, 2019 for now.
C
Community

I was still a bit confused with Dano's answer so I did a little test to get the flow of events in certain scenarios for my reference, but it might be useful to you too. This is for apps that DO NOT use UIApplicationExitsOnSuspend in their info.plist. This was conducted on an iOS 8 simulator + confirmed with iOS 7 device. Please excuse Xamarin's event handler names. They are very similar.

Initial and all subsequent launches from a not-running state:

FinishedLaunching OnActivated

Interruption (phone call, top slide-down, bottom slide-up):

Home button double-press listing inactive apps, then reselecting our app:

OnResignActivation OnActivated

Home button double-press listing inactive apps, selecting another app, then relaunching our app:

Home button single press, then relaunch:

Lock (on/off button), then unlock:

OnResignActivation DidEnterBackground WillEnterForeground OnActivated

Home button double-press, and terminate our app: (subsequent relaunch is first case)

OnResignActivation DidEnterBackground DidEnterBackground (iOS 7 only?)

Yes, DidEnterBackground is called twice on iOS7 device. Both times UIApplication state is Background. However, iOS 8 simulator does not. This needs testing on iOS 8 device. I will update my answer when I get my hand on it, or someone else could confirm.


m
mfaani

applicationWillEnterForeground is called:

when app is relaunched(comes from background to foreground) This method is not invoked when app starts for the first time i.e when applicationDidFinishLaunch is called but only when comes from background applicationDidBecomeActive

applicationDidBecomeActive is called

when app is first launched after didFinishLaunching after applicationWillEnterForeground if there’s no URL to handle. after application:handleOpenURL: is called. after applicationWillResignActive if user ignores interruption like a phone call or SMS. after disappearing of alertView anywhere from the application


Do you by any chance know if this was changed as of iOS 7? I remember (I could be mistaken) doing stuff (iOS 5/6) in applicationWillEnterForeground and having that run when the app first launched. As of now, in 7.1/8, you're right applicationWillEnterForeground doesn't get called on launch.
A
Anson Yao

applicationWillResignActive is called when system is asking for permissions. (in iOS 10). Just in case someone hit into the same trouble as me...


any idea what method get called after permission pop dismiss? I have this issue stackoverflow.com/questions/26059927/…
Q
Qiulang

In iOS 8+ there is a subtle but important difference for taking phone call.

In iOS 7 if user takes phone call both applicationWillResignActive: and applicationDidEnterBackground: are called. But in iOS 8+ only applicationWillResignActive: is called.


u
user2994130

For iOS 13+ the following methods will be executed:

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

关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now