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...
Related
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.
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.
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;
});
}
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.
I am sending email using SMTP Implementation .Now i am switching to another app network to be suspend. How to handle network not to be suspended.
Regards,
Arunkumar.P
Login to iOS Dev Center, and search "background task", you'll find the document you need.
To be more clear, every time your app is to start a task that may take some time to finish and should be alive even in the background, you should declare a UIBackgroundTaskIdentifier before such a task starts, and tell the iOS that this is the task that needs to run in the background. And you also have to make sure that when your task ends, you should always tell iOS that it's finished and no more special background permission is needed.
Your code should look like this:
//right before your critical task starts
UIBackgroundTaskIdentifier newTaskId = UIBackgroundTaskInvalid;
newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
//immediately after your critical task finishes
if (newTaskId != UIBackgroundTaskInvalid) {
[[UIApplication sharedApplication] endBackgroundTask: newTaskId];
}