Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS - How to complete long process in background

My app uploads a video to Facebook. I'd like to complete the upload in the background, even if an impatient user clicks the Home button during the upload.

After some reading, I tried this:

     UIBackgroundTaskIdentifier bti = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
         [[UIApplication sharedApplication] endBackgroundTask:bti];
     }];

     [fb requestWithGraphPath:@"me/videos"
                    andParams:params
                andHttpMethod:@"POST"
                  andDelegate:self];

     [[UIApplication sharedApplication] endBackgroundTask:bti]; 

The work is done with the fb request method. The video is uploaded to Facebook over an http connection. This works fine, but if you background the app by clicking the Home button while the upload is in progress, the upload is suspended. If you foreground the app, the upload resumes.

What I was hoping would happen is that the upload would finish in the background.

Any hope of getting that to work? Am I doing something wrong with the whole beginBackgroundTask thing? It seems too simple to work that way, but that's what the docs seem to say.

Any help, much appreciated.

-- John

like image 443
John Avatar asked Oct 31 '11 20:10

John


People also ask

How long iOS app can run in background?

How long does an iOS app run in the background? An iOS app can run in the background only for 10 minutes.

How do I close background processes in iOS?

You tap and hold your finger on the app icon until it begins to jiggle and you can then press the red “minus” sign to close one or more of these background apps.

What is background processing in iOS?

Unlike Android, iOS has restrictions for the use of background processing in an attempt of improving battery life and user experience. When your apps enter to background mode, it's time developers get out of control of their app. How and when your app gets a chance to execute your task totally depends on the system.


2 Answers

Okay, I figured it out. You need to execute the 'begin' code at the start of a long task that you want to complete in the background, even after the app exits, and then execute the 'end' code when the task completes.

My code above executes the 'end' code way too early, thus ending background execution almost immediately.

The way to do it is to do something like:

   // make sure save can complete in the background
    if ([[UIDevice currentDevice] isMultitaskingSupported])
        backgroundTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{}];

when the long task begins. As hypercrypt, above, says, 'backgroundTaskID must be an ivar or something you can get at later, when the long task completes.

When the task completes, execute something like:

if ([[UIDevice currentDevice] isMultitaskingSupported]) {
    [[UIApplication sharedApplication] endBackgroundTask:backgroundTaskID];
    backgroundTaskID = UIBackgroundTaskInvalid;
}

It works like a charm.

like image 121
John Avatar answered Oct 11 '22 17:10

John


You need to call [[UIApplication sharedApplication] endBackgroundTask:bti]; in the delegate callback. You will need to store the bti in an ivar or as a static variable.

like image 34
hypercrypt Avatar answered Oct 11 '22 18:10

hypercrypt