0

My app allows for downloading a PDF to the device. However, while the PDF is being downloaded, the app is unable to do anything until the download completes. How can I do this so other actions can be handled while download is in progress? This is what I have so far for downloading it.

RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
             NSString *urlString = entry.articlePDF;
             NSURL *url = [NSURL URLWithString:urlString];

             NSData *data = [NSData dataWithContentsOfURL:url];

             NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
             NSString *filename = [entry.articleTitle stringByAppendingString:@".pdf"];
             NSString *removed = [filename stringByReplacingOccurrencesOfString:@"/" withString:@""];
             NSString *documentsDirectory = [paths objectAtIndex:0];

             NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent: removed];
             NSLog(@"Downloadstarted%@", pdfPath);
             [data writeToFile:pdfPath atomically:YES];
Mike Abdullah
  • 14,933
  • 2
  • 50
  • 75
user717452
  • 33
  • 14
  • 73
  • 149
  • 1
    you are downloading the pdf as synchronous request so it will block that thread until all the data downloads from the server, instead of downloading it on main thread download it using asynchronous task. – Manish Agrawal Jun 27 '13 at 05:22

2 Answers2

0

You need to run it in a background thread, like that:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

RSSEntry *entry = [_allEntries objectAtIndex:indexPath.row];
         NSString *urlString = entry.articlePDF;
         NSURL *url = [NSURL URLWithString:urlString];

         NSData *data = [NSData dataWithContentsOfURL:url];

         NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
         NSString *filename = [entry.articleTitle stringByAppendingString:@".pdf"];
         NSString *removed = [filename stringByReplacingOccurrencesOfString:@"/" withString:@""];
         NSString *documentsDirectory = [paths objectAtIndex:0];

         NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent: removed];
         NSLog(@"Downloadstarted%@", pdfPath);
         [data writeToFile:pdfPath atomically:YES];
    })
Avi Tsadok
  • 1,843
  • 13
  • 19
  • Perfect! Is there a notifier for when a file has finished writing to path? – user717452 Jun 27 '13 at 05:26
  • 1
    after the line '[data writeToFile:pdfPath atomically:YES];' the file has finished. If you want to notify the UI, do a dispatch inside of the main thread. Take a look at this link : http://stackoverflow.com/questions/11530050/perform-ui-changes-on-main-thread-using-dispatch-async-or-performselectoronmaint – Avi Tsadok Jun 27 '13 at 07:27
  • Please use `NSURLConnection` directly, with its dedicated **asynchronous** API, rather than kludging together a background synchronous operation like this. Also there is no benefit here to using `DISPATCH_QUEUE_PRIORITY_HIGH` – Mike Abdullah Jul 22 '13 at 14:26
-1

Use ASIHTTPRequest for download

self.request = [ASIHTTPRequest requestWithURL:pdflinkURL];
[self.request setDidFinishSelector:@selector(requestedPDFFinished:)];
[self.request setDidFailSelector:@selector(requestedPDFFailed:)];
[self.request setShouldContinueWhenAppEntersBackground:YES];
self.request.delegate = self;
[self.request setDownloadProgressDelegate:self];
[self.request startAsynchronous];

- (void)requestedPDFFinished:(ASIHTTPRequest *)req
{
    NSData *recievedData = [req responseData];
    // Save top Document Directory
}
//sagar change
- (void)requestedPDFFailed:(ASIHTTPRequest *)req
{
    NSLog(@"%@",req.error);
}
sagarcool89
  • 1,366
  • 8
  • 16