Running task in the background in case application closes - iphone

I am creating an application where i am downloading a large file from dropbox using the drop box sdk. The way the download function works is i make a call to the downloadFile method and pass it a delegate where it will call back as the file starts downloading and after the file fully downloads.
However, right now if a file is downloading and i close the application, the file download pauses until the user goes back into the app.
I have tried using the following code but when i close the app, the download still does not finish until you go back into the app.
UIApplication* app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//This call calls the sdk to start downloading the file. That method will then
// call this classes delegate methods with the progress of the download as well
// as when the file is totally finished downloading
[DBUtils downloadFile:fileVO.filename withHash:fileVO.filehash withRestClient:self.restClient];
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
ANy idea how i can solve this problem?

I'm guessing DBUtils downloadFile:… is an asynchronous method. If that's the case, what you're doing is starting the download then immediately ending your background task.
What you should be doing is setting yourself a delegate method on DBUtils, to let your class know when the download is finished, then calling endBackgroundTask from there.

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.

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

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.

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;
});
}