AFNetworking + big download files + resume downloa

2019-03-11 10:35发布

问题:

I need to download files > 500 Mo with AFNetworking. Sometimes, the time to download them is > 10 minutes and if the app is in background, the download can't be complete.

So I want to try partial downloads. I found a lot of links and this seems to be possible with pause() and resume() methods on AFHTTPRequestOperation.

Actually, I did:

  [self.downloadOperation setShouldExecuteAsBackgroundTaskWithExpirationHandler:^{   
    // Clean up anything that needs to be handled if the request times out
    [self.downloadOperation pauseDownload];
  }];

DownloadOperation is a subclass of AFHTTPRequestOperation (singleton).

And in AppDelegate:

- (void)applicationWillEnterForeground:(UIApplication *)application
{
  // resume will only resume if it's paused...
  [[DownloadHTTPRequestOperation sharedOperation] resumeDownload];  
}

The server is OK to get the new range in headers...

My questions:

1) Is-t the good way to do it ? 2) Does the resume needs to change the outputStream (append:NO => append:YES) ? Or is-it managed somewhere by AFNetworking ? (don't find)

self.outputStream = [NSOutputStream outputStreamToFileAtPath:self.filePath append:YES];

Something like this (in DownloadHTTPRequestOperation):

- (void)pauseDownload
{
  NSLog(@"pause download");
  [self pause];
}

- (void)resumeDownload
{
  NSLog(@"resume download");
  self.outputStream = [NSOutputStream outputStreamToFileAtPath:self.filePath append:YES];
  [self resume];
}

Thanks for your help.

回答1:

Update:

As steipete may wont maintain AFDownloadRequestOperation any more (https://github.com/steipete/AFDownloadRequestOperation/pull/68). NSURLSessionDownloadTask may be a better choice.


https://github.com/steipete/AFDownloadRequestOperation

Also, I write a lib base on AFDownloadRequestOperation: https://github.com/BB9z/RFDownloadManager



回答2:

I ended up using the old (non ARC) ASIHTTPRequest framework for a similar task. AllowResumeForFileDownloads does what you need. Note that you server needs to support resuming by reading the Range http header.

if (![[NSFileManager defaultManager] fileExistsAtPath:downloadPath]){
    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
    [request setDelegate:self];
    [request setAllowResumeForFileDownloads:YES];
    [request setDownloadDestinationPath:downloadPath];
    [request setTemporaryFileDownloadPath:tmpPath];
    [request startAsynchronous];
}