BackgroundTask not stopping when application comes foreground in ios - iphone

I am using beginBackgroundTaskWithExpirationHandler to get 10 minutes extra time for the application to run in background. But I need to stop this background task if the application comes foreground within the provided 10 minutes of time. My code is as follows
- (void)applicationDidEnterBackground:(UIApplication *)application
{
bgTask = [application beginBackgroundTaskWithExpirationHandler: ^ {
NSLog(#"invalidate back task in didenter %#",[application backgroundTimeRemaining]);
if (bgTask != UIBackgroundTaskInvalid) {
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
}];
//Background tasks require you to use asyncrous tasks
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(#"\n\nRunning in the background inside DidEnterBackground %f!\n\n", [application backgroundTimeRemaining]);
while ([application backgroundTimeRemaining] > 1.0) {
NSLog(#"\n\nRunning in background %f!\n\n", [application backgroundTimeRemaining]);
sleep(5);
}
[application endBackgroundTask: bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}
And when app comes foreground I am ending background task like this
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
bgTask is declared globally in .h file. When app goes foreground its still running the background task with showing backgroundTimeRemaining as a long integer value. I am not getting how to stop the background task please help me.
Thanks

Related

location service in the background execution

I want to get the location of my device 24x7 times. but as per apple documentation, apps can only be run for the max 10 minutes.After that, apps is automatically killed.
I am using the below code:
- (void)applicationWillResignActive:(UIApplication *)application
{
UIApplication * app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler: ^ {
dispatch_async (dispatch_get_main_queue (), ^ {
if (bgTask != UIBackgroundTaskInvalid)
{
[app endBackgroundTask: bgTask];
bgTask = UIBackgroundTaskInvalid;
}
});
}];
// Start the long-running task and return immediately.
dispatch_async (dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^ {
lm.locationManager.distanceFilter = kCLDistanceFilterNone;
lm.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
[lm.locationManager startMonitoringSignificantLocationChanges];
[lm.locationManager startUpdatingLocation];
dispatch_async (dispatch_get_main_queue (), ^ {
if (bgTask != UIBackgroundTaskInvalid) {
[app endBackgroundTask: bgTask];
bgTask = UIBackgroundTaskInvalid;
}
});
});
}
I have also included supported Background Mode as Requires location.
But the app runs for only 10 minutes. How can i make the app to run all the time. Please help me out!
significantLocationChanges does not require you to implement the background task. just remove the bgtask creation and run it normally with the Supported Background Mode key.
Scheduled BackgroundTasks are killed by OS approx after 10 mins and hence your location service monitoring. So u only need to remove the BGTask that u are creating for location updates.

Is it possible to call webRequest when application goes in background?

I want to upload images when home button pressed and application goes in background.
Is it possible? If yes then how? and if no then do i have any other alternative?
Thanks in advance...
You can perform a task in background by using this code for a specific time-
UIBackgroundTaskIdentifier bgTask = 0;
UIApplication *app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
}];
self.silenceTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self
selector:#selector(startLocationServices) userInfo:nil repeats:YES];
Refer this:
http://developer.apple.com/library/ios/#documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html
I think this will help u. :)
An app can request to run in the background for up to 10 minutes after it has been closed so that it can finish a long-running task. Only some processes are allowed to run in background. See Implementing Long-Running Background Tasks section in this reference.
If your app is allowed so, you can try below code:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UIBackgroundTaskIdentifier bgTask;
bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
// 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;
});
}
if you want to know how much time your app has left to run
NSTimeInterval ti = [[UIApplication sharedApplication]backgroundTimeRemaining];
NSLog(#"Remaining Time: %f", ti); // just for debug
For more ref go with this reference PDF(page 60)

After 10 minutes background app is not close

I am uploading some pictures to server in background. I want to close app after 10 mins. But my app is not closing, it is in pause mode in background and when I press app icon upload operation again starts in foreground. I used below code:
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
// Clean up any unfinished task business by marking where you.
// stopped or ending the task outright.
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Here goes your operation
// done!
upload_photo();
dispatch_async(dispatch_get_main_queue(), ^{
if (bgTask != UIBackgroundTaskInvalid)
{
// if you don't call endBackgroundTask, the OS will exit your app.
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
});
});
My Question: How can I close my app after 10 min.(upload task complete or not)?
Thanks in advance.

SIP deregistration using PJSIP

In our app, we need to de-reg a user when he pushes the app to the background.
We are using PJSIP. My applicationDidEnterBackground:
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(#"did enter background");
__block UIBackgroundTaskIdentifier bgTask;
bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self deregis];
[application endBackgroundTask: bgTask]; //End the task so the system knows that you are done with what you need to perform
bgTask = UIBackgroundTaskInvalid; //Invalidate the background_task
NSLog(#"\n\nRunning in the background!\n\n");
});
}
The deregis method is as below:
- (void)deregis {
if (!pj_thread_is_registered())
{
pj_thread_register("ipjsua", a_thread_desc, &a_thread);
}
dereg();
}
And the de-reg method is as below:
void dereg()
{
int i;
for (i=0; i<(int)pjsua_acc_get_count(); ++i) {
if (!pjsua_acc_is_valid(i))
pjsua_buddy_del(i);
pjsua_acc_set_registration(i, PJ_FALSE);
}
}
When we push the app to the background, the dereg gets called. But when the server sends back a 401 challenge, the stack isn't sending back the auth details in SIP call until I bring the application back to foreground.
Does anyone have any idea why this is happening?
Thanks,
Hetal
You don't want to end the background task in your background thread:
e.g.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self deregis];
// don't do below...
// [application endBackgroundTask: bgTask]; //End the task so the system knows that you are done with what you need to perform
// bgTask = UIBackgroundTaskInvalid; //Invalidate the background_task
NSLog(#"\n\nRunning in the background!\n\n");
});
You want to end the background task when the registration is updated. So you need to hook into the pjsua on_reg_state callback.
e.g. this example may only assume one unregister, for multiple accounts you have to wait until all are unregistered
-(void) regStateChanged: (bool)unregistered {
if (unregistered && bgTask != UIBackgroundTaskInvalid) {
[application endBackgroundTask: bgTask]; //End the task so the system knows that you are done with what you need to perform
bgTask = UIBackgroundTaskInvalid; //Invalidate the background_task
}
}

iPhone background task stops running at some point

In my iPhone app I have a background task that starts running when the app enters the background state.
The task runs fine and is structured in a loop like this:
run.
sleep for 5 min.
run.
sleep for 5 min.
etc.
For some reason, the task stops running after a certain amount of time... say half an hour to an hour.
Can anyone help me understand why?
Here is the background task code:
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(#"Application entered background state.");
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"bgCheckSwitch"] == YES) {
//UIApplication* app = [UIApplication sharedApplication];
// Request permission to run in the background. Provide an
// expiration handler in case the task runs long.
NSAssert(bgTask == UIBackgroundTaskInvalid, nil);
bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
// Synchronize the cleanup call on the main thread in case
// the task actually finishes at around the same time.
dispatch_async(dispatch_get_main_queue(), ^{
if (bgTask != UIBackgroundTaskInvalid)
{
[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.
[someClass doSomeThing]; //The actual method performed by the task. The looping is in the method.
dispatch_async(dispatch_get_main_queue(), ^{
if (bgTask != UIBackgroundTaskInvalid)
{
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
});
});
}
}
A background task only runs for a period of time, then the OS kills it. This is discussed in the multitasking WWDC10 videos.