When an iOS application goes to the background, are lengthy tasks paused?
Asked Answered
P

3

75

Yes, I know if I wish my app to be responsive to users' multitasking actions, such as switch to another app, I should deal with

- (void)applicationWillResignActive:(UIApplication *)application
- (void)applicationDidBecomeActive:(UIApplication *)application

What if my app is doing a quite-long time consuming operation (like downloading a big file) and the user causes my app to enter the background? Will that operation automatically be suspended and resumed when the user comes back to my app?

What exactly will happen behind the scene when my app enters the background or resumes in the foreground?

What if when users let my app go to the background my app's execution is just in the middle of a method?

For e.g., my app is doing

for (int i = 1 to 10000K) {
    do some calculation;
}

When i== 500K, user switches to another app. What happens to the for-loop in my app?

Presbytery answered 11/7, 2011 at 13:22 Comment(2)
I think its very good question, but have you actually took the time to test and figure out what happens when it goes to the background? I mean, put an NSLog inside the loop somewhere and see what happens...Evaporation
Firstly, following micpringle's suggestion below is advisable. Second, if I recall correctly, aren't there seven very specific APIs that are allowed to run in the background? Look at those and see if they fit the bill. If they don't, maybe you need to redesign the way your application does things.Aggrieve
C
78

From the documentation:

Return from applicationDidEnterBackground(_:) as quickly as possible. Your implementation of this method has approximately five seconds to perform any tasks and return. If the method doesn’t return before time runs out, your app is terminated and purged from memory.

If you need additional time to perform any final tasks, request additional execution time from the system by calling beginBackgroundTask(expirationHandler:). Call beginBackgroundTask(expirationHandler:) as early as possible. Because the system needs time to process your request, there’s a chance that the system might suspend your app before that task assertion is granted. For example, don’t call beginBackgroundTask(expirationHandler:) at the very end of your applicationDidEnterBackground(_:) method and expect your app to continue running.

If the long-running operation you describe above is on the main thread and it takes longer than 5 seconds to finish after your application heads to the background, your application will be killed. The main thread will be blocked and you won't have a chance to return from -applicationDidEnterBackground: in time.

If your task is running on a background thread (and it really should be, if it's taking long to execute), that thread appears to be paused if the application returns from -applicationDidEnterBackground: (according to the discussion in this answer). It will be resumed when the application is brought back to the foreground.

However, in the latter case you should still be prepared for your application to be terminated at any time while it's in the background by cleaning things up on your way to the background.

Cementite answered 11/7, 2011 at 16:8 Comment(1)
This is confusing. beginBackgroundTaskWithExpirationHandler grants your app 10 minutes (a lot!) to finish things, but "still be prepared for your app to be terminated at any time while it's in the background" ??? which is true? My ~10 second tasks are using CoreGraphics to render images (as thumbnails) and process them on background tasks, and they hang!!! forever when app goes to background. What is allowed to the app within the 'beginBackgroundTaskWithExpirationHandler' period?Featherbrain
P
12

If you are doing some operation which might consume time and you don't want to kill it then you can extend the time for your operation by executing in UIBackground Task i

{
    UIBackgroundTaskIdentifier  taskId = 0;
    taskId = [application beginBackgroundTaskWithExpirationHandler:^{
        taskId = UIBackgroundTaskInvalid;
    }];

// Execute long process. This process will have 10 mins even if your app goes in background mode.

}

The block argument called "handler" is what will happen when the background task expire (10min). Here is a link to the documentation

Prefect answered 1/6, 2013 at 21:23 Comment(2)
This worked when app enters background. What is solution when app gets killed e.g. applicationWillTerminate(_ application: UIApplication)Adolfoadolph
Can you elaborate just a little more? 1.) what is the right time to call 'beginBackgroundTaskWithExpirationHandler' ? could I do it from within 'applicationWillResignActive' or 'applicationDidEnterBackground' ? 2.) Will the expiration handler be called while app is in background? on what thread/queue? what can be done in this handler, and what cannot? 3.) my app uses CoreGraphics to render images in the background - and some CG methods hang their threads in the background. Will they survive better within such a 'backgroundTask' ???Featherbrain
V
0

Like mentioned above, there are a few cases where your app runs in the background and apple can allow or deny depending on what you are doing.

https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html

More importantly if you do fit into one of these categories your app refresh rate is determined by an apple algorithm that takes into consideration your app usage on that device vs other apps. If your app is used more often then it gets more background time allotted. This is just one variable but you get the idea that background time allocation varies app to app and not under your control.

Vulgate answered 11/11, 2013 at 13:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.