Search code examples
iphonedownloaduiapplicationdelegatedownload-manager

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.


Solution

  • 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.