I need to keep getting user's location updates when app going to background and, as I found in Apple's documentation, this is one of the long-running background tasks that are allowed to be implemented. I also need to make some processing and network calls to send to server some info when location updates are notified. What I'm trying to do, in broad strokes, is something like this:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Background task
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"Background time remaining: %f seconds (%d mins)",
[[UIApplication sharedApplication] backgroundTimeRemaining],
(int)([[UIApplication sharedApplication] backgroundTimeRemaining] / 60));
// Need to get data from database here
// Finished
if (bgTask != UIBackgroundTaskInvalid) {
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
});
// Start location manager
locationManager = [[CLLocationManager alloc] init];
if ([CLLocationManager locationServicesEnabled]) {
locationManager.delegate = self;
locationManager.distanceFilter = 20;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Want to perform some data processing here, including concurrent tasks
// and several network calls to get and send data to server
[self locationProcessingCompleted];
});
}
- (void)locationProcessingCompleted
{
// Check results. If needed, some more data processing and several network
// calls to send data to server
// Close background task
if (bgTask != UIBackgroundTaskInvalid) {
[[UIApplication sharedApplication] endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
}
I don`t find any code example of a long-running background task regarding location services, and I have several questions about it:
a) Is it necessary to execute all the background code within a dispatch_async
queue? In other words, has all the code in applicationDidEnterBackground:
to be executed asynchronously, including the location manager settings?
b) [[UIApplication sharedApplication] backgroundTimeRemaining]
is returning a very long value. This time is not supposed to be around 10 minutes?
c) I want to do: perform an initial finite-length task, start location updates, and then perform some other finite-length tasks every time that didUpdateToLocation:
is triggered. I have set the location
value of UIBackgroundModes
in Info.plist
. Is my approach correct? Will I keep locations being updating indefinitely, and then can I perform a finite-length task less than 10 min long at every update received?
Please, I need help with this issues. Thanks in advance