简体   繁体   中英

NSURLSession: can't get resume data after calling cancelByProducingResumeData

I want to resume downloading after user cancels downloading or something wrong happens. But when I call cancelByProducingResumeData method, the resumeData is nil . So, I can't resume downloading. I'm sure the download link can be resumed, because our PC client can resume downloading of this link. Here is my code. Here is the full project .

#import "ViewController.h"

@interface ViewController ()
{
    NSURLSession *_session;

}

@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
@property NSURLSessionDownloadTask *netTask;
@property NSData *resumeData;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    if (_session == nil) {
        NSURLSessionConfiguration *confi = [NSURLSessionConfiguration defaultSessionConfiguration];
        _session = [NSURLSession sessionWithConfiguration:confi delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    }
}
- (IBAction)startAction:(id)sender {
    [self start];
}
- (IBAction)stopActon:(id)sender {
    [self stop];
}

- (void)stop {
    __weak typeof(self) vc = self;
    [self.netTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
        vc.resumeData = resumeData;
        vc.netTask = nil;
    }];
}

- (void)start {
    if (self.resumeData != nil) {
        self.netTask = [_session downloadTaskWithResumeData:self.resumeData];
    } else {
        NSURL *downlaodURL = [NSURL URLWithString:@"http://sdl24.yunpan.cn/share.php?method=Share.download&cqid=37ef0df7c8155bacf55c237bd433ddd8&dt=24.02b6cbb4148de503fe35ddab08dac35b&e=1459317290&fhash=41181b28ff97806ef8469842b4a5eabc330a0c60&fname=feistudy%2B%2B%25E8%25AF%25AD%25E8%25A8%2580%25E5%25AD%25A6%25E4%25B9%25A0%25E6%2596%25B9%25E6%25B3%2595%25E8%25AE%25BA%25E8%25BF%25B0&fsize=87624815&nid=14471440239484082&st=e08142ab7c935cdd15ecc8851c82e819&xqid=22309244"];
        self.netTask = [_session downloadTaskWithURL:downlaodURL];
    }
    [self.netTask resume];
}

- (NSString*)filePath
{
    NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *path = [doc stringByAppendingPathComponent:@"p.rmvb"];
    return path;
}

#pragma mark - NSURLSessionDownloadDelegate
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location
{
    dispatch_async(dispatch_get_main_queue(), ^{

        NSFileManager *manager = [NSFileManager defaultManager];
        [manager moveItemAtPath:location.path toPath:[self filePath] error:nil];
        NSLog(@"locaton.path:%@", location.path);
        NSLog(@"filePaht:%@",[self filePath]);
    });

}

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
      didWriteData:(int64_t)bytesWritten
 totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{

    dispatch_async(dispatch_get_main_queue(), ^{
        double progress = totalBytesWritten/(double)totalBytesExpectedToWrite;
        NSLog(@"progress:%f",progress);
        self.progressView.progress = progress;
    });

}

#pragma mark - NSURLSessionTaskDelegate
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(nullable NSError *)error
{
    if (error) {

        NSData *resumeData = error.userInfo[NSURLSessionDownloadTaskResumeData];
        self.resumeData = resumeData;
    }



}

@end

There's a long list of requirements for when resume data can be obtained. Among other things:

  • The response must contain an ETag or Last-Modified header.
  • I think the response must also contain an Accept-Ranges: bytes header
  • The temporary file must still exist (not low on disk space).
  • It must be an HTTP or HTTPS request.
  • The Last-Modified or ETag header must indicate that the file hasn't changed since it was last requested.

There might be other requirements that I'm forgetting, eg HTTP/1.1.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM