Search code examples
iosobjective-clong-running-processes

iOS: Long-Running task


This is the example from developer.apple.com

Finite-Length Tasks
Starting a background task at quit time

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    bgTask = [application beginBackgroundTaskWithName:@"MyTask" expirationHandler:^{
        // Clean up any unfinished task business by marking where you
        // stopped or ending the task outright.
        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];

    // Start the long-running task and return immediately.
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        // Do the work associated with the task, preferably in chunks.

        [application endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    });
}

I want to implement the Long-Running Task, not the "Finite-Length" one. I've not found any examples written with objective-c for current version sdk. Can I start it, say, on application start and run it continuously wheter app is in foreground or background? How do i do that?

I'm a react-native developer, and i've just begun learning objective-c. Therefore i may need just simple example to follow. I've already implemented bridge instance to Cocoa Touch Class, it works fine. All i need is to launch the Long-Running Task in this class. I need it for BLE, but for sake of simplicity, i'd say, let's use location tracking, as it's easier and quicker to test.

My LongRunningTask.m:

#import "LongRunningTask.h"

@implementation LongRunningTask

RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(start:(RCTResponseSenderBlock)callback)
{
  // start the Long-Running Task here
  callback(@[@"done"]);
}

I don't get it, how is long-running task being defined? Seems, there is no specific method or any marker, which would declare a task to be long-running. So, technically, if i'm getting permission from user to run a specific type of long-running task, i can continuously run whatever code i want within applicationDidEnterBackground? Even if it has nothing in common with the permission i've got?

And the only factor that affects if this task will be terminated in 10-ish minutes is if i've got the permission or not?

Thank you!


Solution

  • For the term Long-Running Task means the task which is active until the app has been killed, I am giving you simple example of LocationManager

    When you setup your app to receive Location Updates and initialize the LocationManager the app is subjected to receive location updates until you stop the updates in foreground, same is the case with BLE.

    See the examples,

    _locationManager=[[CLLocationManager alloc] init];
    _locationManager.delegate=self;
     if ([_locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
            [_locationManager requestWhenInUseAuthorization];
            [_locationManager requestAlwaysAuthorization];
     }
    [_locationManager startUpdatingLocation];
    

    The above code starts the LocationManager for the app to receive GPS location updates if the user has given permission to the app to receive GPS location and if the GPS settings for app is ON to receive updates, the method below will get called till your app is in Foreground

    -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
    

    Same happens with BLE

    If you want your app to be able to receive GPS or, BLE updates in Background you need to turn on related Background Modes from the Project Settings of the app as shown below in the image

    enter image description here

    The image shows the list of services you can run while app in background, apart from the list you can do certain network activities like downloads and uploads which you have shown in your example, which will run a Long-Running Task, until you kill the app, or the service is interrupted from settings by user manually.

    Hope above clears your doubt.

    Cheers.