Click here to Skip to main content
15,888,610 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
Hi,

All documentations I could find so far regarding background tasks in iOS is almost related to achieving a single task. But what if a task is to be repeated in background ?
I could not figure out how to manage this as it sounds to me that as soon as the task is finished,
endBackgroundTask has to be called to close the previous task and beginBackgroundTaskWithExpirationHandler has to be called for the new task to be started.

That's what the code below is supposed to do, but it does not work :
- as long as my application is foreground, it works (notice that task id is always increasing, where I thought it would stay to 1, as only one task is started at a given time, which is, I guess, already as issue).
- when I enter background mode, remaining time is descreasing until task is finished, but no new task is started.
I guess this is because there is thus no more background task running, but the truth is I need to start a backgound task while in background ...
I think this is not the good way in managing this and need some help in starting the right way.

Thanks in advance.


#import "AppDelegate.h"

@implementation AppDelegate

UIBackgroundTaskIdentifier backgroundTask;
NSTimer *timer = nil;
bool processDone =false;


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    backgroundTask = UIBackgroundTaskInvalid;
    timer = [NSTimer scheduledTimerWithTimeInterval:(0.1) target:self selector:@selector(timerFunc) userInfo:nil repeats:YES];
    
    backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        [[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
        backgroundTask = UIBackgroundTaskInvalid;
    }];
    NSLog(@"init : new task started (%d)", backgroundTask);
    
    dispatch_queue_t queue;
    queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        processDone = false;
        [self process];
    });
    
    return YES;
}
							

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    NSLog(@"applicationDidEnterBackground");
}

-(void)timerFunc
{
    double remaining = [UIApplication sharedApplication].backgroundTimeRemaining;
    if (remaining < 1000.0)
        NSLog(@"Background -> time remaining = %.1f seconds", remaining);
    else
        NSLog(@"Foreground");
    
    if (processDone)
    {
        NSLog(@"processDone : endBackgroundTask (%d)", backgroundTask);
        if (backgroundTask != UIBackgroundTaskInvalid)
        {
            [[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
            backgroundTask = UIBackgroundTaskInvalid;
        }

        NSLog(@"processDone : beginBackgroundTaskWithExpirationHandler");
        backgroundTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
            [[UIApplication sharedApplication] endBackgroundTask:backgroundTask];
            backgroundTask = UIBackgroundTaskInvalid;
        }];
        NSLog(@"processDone : new task started (%d)", backgroundTask);
        
        dispatch_queue_t queue;
        queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        dispatch_async(queue, ^{
            processDone = false;
            [self process];
        });

    }
}


- (void)process
{
    sleep(5);
    processDone = true;
}

@end
Posted
Updated 24-Sep-14 2:53am
v3

1 solution

Background tasks are not wanted by Apple design. You should keep that really in mind.

A good tutorial is from the Ray Wenderlich.

Another solution can be Notifications.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900