Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ios 13 objective-c background task request

I've got a question with objective-c and background task request.

Restricted to background modes with ios 13.

My App does not run in the background more than 30 seconds.

Background modes changed with ios 13.

I need to register a background task with objective-c like this:

BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.SO.apprefresh", using: nil) { task in
    self.scheduleLocalNotification()
    self.handleAppRefreshTask(task: task as! BGAppRefreshTask)
}

and I need schedule when app goes to background

func scheduleAppRefresh() {
    let request = BGAppRefreshTaskRequest(identifier: "com.SO.apprefresh")
    request.earliestBeginDate = Date(timeIntervalSinceNow: 2 * 60) // App Refresh after 2 minute.
    do {
        try BGTaskScheduler.shared.submit(request)
    } catch {
        print("Could not schedule app refresh: \(error)")
    }
}
like image 595
Hakan Turkmen Avatar asked Sep 28 '19 20:09

Hakan Turkmen


People also ask

What are background tasks on Iphone?

Overview. Use the BackgroundTasks framework to keep your app content up to date and run tasks requiring minutes to complete while your app is in the background. Longer tasks can optionally require a powered device and network connectivity.

How do you simulate background fetch?

To simulate background fetch, from the tab bar > Debug > Simulate background fetch. Note that it works only when running on real devices.

How long will an iOS app run in the background?

When your app moves to the background, the system calls your app delegate's applicationDidEnterBackground(_:) method. That method has five seconds to perform any tasks and return. Shortly after that method returns, the system puts your app into the suspended state.


1 Answers

There is hardly any complete example for a BGProcessingTaskRequest in Objective-C. This is my implementation, which leans on the other answers in this question.

The following steps are needed.

Add the BackgroundTasks.framework to you app, under Build Phases - Link Binary With Libraries

Enable Background processing in Signing & Capabilities - Background Modes. I enabled Background fetch & Remote notifications as well.

Edit your Info.plist. Enter a new row 'Permitted background task scheduler identifiers'. Add items for that row with the identifiers of your background tasks. In my case: com.toolsforresearch.compress and a second item com.toolsforresearch.upload.

#import <BackgroundTasks/BackgroundTasks.h>

in your AppDelegate.m

Add this to willFinishLaunchingWithOptions in AppDelegate.m:

if (@available(iOS 13.0, *)) {
    NSLog(@"configureProcessingTask");
    [self configureProcessingTask];
}

Add this to applicationDidEnterBackground in your AppDelegate.m

if (@available(iOS 13.0, *)) {
    NSLog(@"scheduleProcessingTask");
    [self scheduleProcessingTask];
}

Finally, add this to your AppDelegate.m, before the @end

static NSString* uploadTask = @"com.toolsforresearch.upload";

-(void)configureProcessingTask {
    if (@available(iOS 13.0, *)) {
        [[BGTaskScheduler sharedScheduler] registerForTaskWithIdentifier:uploadTask
                                                              usingQueue:nil
                                                           launchHandler:^(BGTask *task) {
            [self scheduleLocalNotifications];
            [self handleProcessingTask:task];
        }];
    } else {
        // No fallback
    }
}

-(void)scheduleLocalNotifications {
    //do things
}

-(void)handleProcessingTask:(BGTask *)task API_AVAILABLE(ios(13.0)){
    //do things with task
}

-(void)scheduleProcessingTask {
    if (@available(iOS 13.0, *)) {
        NSError *error = NULL;
        // cancel existing task (if any)
        [BGTaskScheduler.sharedScheduler cancelTaskRequestWithIdentifier:uploadTask];
        // new task
        BGProcessingTaskRequest *request = [[BGProcessingTaskRequest alloc] initWithIdentifier:uploadTask];
        request.requiresNetworkConnectivity = YES;
        request.earliestBeginDate = [NSDate dateWithTimeIntervalSinceNow:5];
        BOOL success = [[BGTaskScheduler sharedScheduler] submitTaskRequest:request error:&error];
        if (!success) {
            // Errorcodes https://stackoverflow.com/a/58224050/872051
            NSLog(@"Failed to submit request: %@", error);
        } else {
            NSLog(@"Success submit request %@", request);
        }
    } else {
        // No fallback
    }
}

When I run my app and push it to the background these messages are NSLogged:

2020-05-07 19:12:45.179834+0200 SessionVideo[819:171719] scheduleProcessingTask
2020-05-07 19:12:45.219117+0200 SessionVideo[819:171719] Success submit request <BGProcessingTaskRequest: com.toolsforresearch.upload, earliestBeginDate: 2020-05-07 17:12:50 +0000, requiresExternalPower=0, requiresNetworkConnectivity=1>

I did no processing yet in the BGProcessingTask, but the fact that the request submits fine is a good starting point. Comments are more than welcome, for instance how to add a completion handler to the background task.

like image 122
Jan Ehrhardt Avatar answered Nov 15 '22 18:11

Jan Ehrhardt