Hank Brekke
Hank Brekke

Reputation: 2024

iOS Application Background Downloading

Hey! I need to know how I can have my iOS Application start a download in the background of the application (like, have the download run in the AppDelegate file) so changing ViewControllers will not interrupt or cancel the download. I also need to be able to get the progress of the download (0.00000 - 1.00000), to set a UIProgressView object to, which also means I need a - (void)progressDidChangeTo:(int)progress function.

Upvotes: 8

Views: 29998

Answers (2)

Piotr Czapla
Piotr Czapla

Reputation: 26532

Just use ASIHTTPRequest it is way easier than NSURLRequest and does exactly what you need. It examples that shows how to download in background and how to report progress.

I wouldn't download anything in the AppDelegate directly. Instead I would create a separated class just for that purpose. Let's call it MyService I would then initialize that class in my app delegate.

The class can work as a singleton or can be passed to each view controller that requires it.

In MyService class I would add the ASINetworkQueue and few methods to handle the requests when they are ready. Here is the code from ASI examples that you can use:

- (IBAction)startBackgroundDownloading:(id)sender
{
   if (!self.queue) {
      self.queue = [[[ASINetworkQueue alloc] init] autorelease];
   }

   NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
   ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
   [request setDelegate:self];
   [request setDidFinishSelector:@selector(requestDone:)];
   [request setDidFailSelector:@selector(requestWentWrong:)];
   [self.queue addOperation:request]; //queue is an NSOperationQueue
   [self.queue go];
}

- (void)requestDone:(ASIHTTPRequest *)request
{
   NSString *response = [request responseString];
   //Do something useful with the content of that request.
}

- (void)requestWentWrong:(ASIHTTPRequest *)request
{
   NSError *error = [request error];
}

If you need to set the progress bar. I would just expose the setDownloadProgressDelegate of ASINetworkQueue in my MyService class and set it in my ViewControllers like that:

[[MyService service] setDownloadProgressDelegate: self.myUIProgressView];

BTW. If you need to continue downloading even when your app exits you can set ShouldContinueWhenAppEntersBackground property of your request to YES.

Upvotes: 18

Moszi
Moszi

Reputation: 3236

you can use NSURLConnection to start an asynchronous request that won't cause your UI to be frozen. You can do it by doing something like:

NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:url];
connection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
[urlRequest release];

in order to have your progress you can use the:

connection:didReceiveResponse:(NSURLResponse *)response;

delegate call to inspect the response.expectedContentLength and then use the

connection:didReceiveData:(NSData *)data

to track the amount of data that was downloaded and calculate a percentage.

Hope this helps, Moszi

Upvotes: 3

Related Questions