iOS - How to finish a task before the App enter background - iphone

I'm developing an App and I'm facing a problem when users quit the app.
Let's say the app is downloading 3 images.
The user quits the app.
How can I continue the download (because we're talking about 2 mo left and not 500 !)?
I know something like this :
if ([_downloader isDownloading]) {
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), ^{
NSLog(#"dispatch_async debut");
// Do the work associated with the task, preferably in chunks.
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
NSLog(#"dispatch_async fin");
});
}
The problem is that my task is already processing. I don't want to start again the download !
Do you have any ideas ?
Thanks a lot for your answers.

I would advise using ASIHTTPRequest that has a built in option for resuming active downloads.
http://allseeing-i.com/ASIHTTPRequest/

The only way is to download the data in a synchronous way with
[NSData dataWithContentsOfURL:imageURL]
This approach is not the best.
You should consider a differente approach that is to create a queue of NSOperations and, before go in background, store the queue and kill the queue, queue that you can simply restore once the app returns in foreground.

Related

Background task in objective c

I have a VOIP application in objective-c
SIP call is working fine when application is in foreground.
My problem is when my app is in background SIP call is not working after 10 minutes after going to background.
I have started a background task in applicationDidEnterBackground
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;
});
In plist file UIBackgroundModes is set to voip
I am in a patience for it.
Please any body help me. Please.
By my understanding the beginBackgroundTaskWithExpirationHandler method is used for executing a Finite-Length Task in the Background. See Here. And there is no way extend that period of 10 mins which I have discovered.
Since your app classifies as a background mode required app, I dont think you will be needing
beginBackgroundTaskWithExpirationHandler.
Read "Implementing a VoIP App" section in the above link.It advocates the use of setKeepAliveTimeout:handler: method.

Background downloading even if the phone gets locked

I am trying to implement an application for iPhone that should simply download some content out of the web. This download is quite big, so I implemented the download as a background task to give the user the chance to do some other stuff with his phone while downloading. My problem is that if the user pushes the lock button (or if auto lock kicks in) the applicationWillResignActive: in the AppDelegate is called and after about ten seconds the download is aborted because the phone does not enter background and just stays inactive.
My question is what am I doing wrong? How can I ensure that the download is continued, even if the phone is locked?
Thanks in advance.
You need to surround the downloading code with background task block like this:
UIApplication* app = [UIApplication sharedApplication];
UIBackgroundTaskIdentifier bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
//here you need to finish what you are doing evven if you've not finished yet, otherwise your app will be killed
[app endBackgroundTask:bgTask];
}];
//here comes your downloading code
[app endBackgroundTask:bgTask];
This will give you 10 minutes(according to some other posts) to execute code in background...

Application delegates are not calling while application entered into background

I am implementing an iPhone application.I am downloading data from server by using asynchronous request in the application.If, I Press the home button, My application delegate is not calling directly.After completion of data downloading from server, application delegate methods are calling.So, How can i get the immediate Delegate call in my application.
Any help can be appreciate.
Which delegate methods are you implementing? Can you post what you've tried (code-wise) here? Note that once your application has been moved to the background, you can only run short-term tasks to preserve battery life.
This example is provided by Apple:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UIApplication* app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
// Clean up any unfinished task business by marking where you.
// stopped or ending the task outright.
[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, preferably in chunks.
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}
If you want to perform longer running tasks, you require special permissions, and even then can only perform a certain subset of actions. They are discussed here:
iOS App Programming Guide: App States and Multitasking

Iphone: Does application freeze when run into background?

I have an application that upload file to server using NSUrlConnection. It was placed on ViewDidLoad method. It did upload to server while the application is in foreground. Before I call the NSUrlConnection asynchronously, I create temporary file in application directory.
While the files were uploading, I clicked on the iPhone button so that the application will run in the background. First thing I thought the application freeze the upload, but it doesn't. The file still uploading during that time.
Does that mean the application still running normally at the background until the remaining time finished then the application quits?
Once the home button is pressed, every application runs in the background for a certain amount of time(usually few seconds) before it enters suspended mode. If you are required to complete a task(in your case file upload) before entering suspended mode, you can use Task completion API.
Even if you are using task completion API, only one thread of your application is running, but not the whole application. Here is the code recommended by apple:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UIApplication* app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[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.
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}

How do I end a task gracefully in the expiration handler before iOS terminates the app?

We want to logout our app once the expiration handler is invoked. This works some of the time, but it appears there are times when it just kills the process hard even though we end the background task by calling endBackgroundTask. It almost seems like our logout process in this case is taking too long and iOS just kills it. This shouldn't be a long task, but is there any way to request additional time?
if ([app respondsToSelector:#selector(beginBackgroundTaskWithExpirationHandler:)]) {
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) {
backgroundKilled = true;
[self logoutAll];
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
});
}];
}
Here is a good UIApplication delegate overview, covers what the app goes through when being terminated.
iOS gives you ten minutes for your background task. Is your logout process taking that long?