Actually I am working for multitasking and facing error please assist me, as I need to work on background application and also in foreground application
- (void)applicationDidEnterBackground:(UIApplication *)application
{
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 = [app 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)
{
[app 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.
// Synchronize the cleanup call on the main thread in case
// the expiration handler is fired at the same time.
dispatch_async(dispatch_get_main_queue(), ^{
if (bgTask != UIBackgroundTaskInvalid)
{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
});
});
}
Put in your #interface:
UIBackgroundTaskIdentifier bgTask;
(out from NDA now).
Check out the developer documentation, if you have a developer's account. We can't really answer the os4.0 question because it's under NDA, but all the information you'll need to answer that question is on that page (once logged in).
Related
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.
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.
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
}
}
I am doing SMTP related app in my application, to send the mail.In IOS 4 background execution exceptions for audio,voip,location.How to use network operation.
There is no explicit exception for network access. You can request extra time to complete a task after your app exits but you can't create a daemon process that continually runs in the background.
Apple provides 600 sec to execute background task you can take help with code
UIApplication *app = [UIApplication sharedApplication];
self.bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
while (1) {
NSLog(#"BGTime left: %f", [UIApplication sharedApplication].backgroundTimeRemaining);
[self.viewController performSelector:#selector(invokeCuisineSelector)];
sleep(1);
}
});
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.