随笔 --- IOS网络请求断点续传

iOS 中如何实现断点续传的功能

思路:

001 该类继承NSURLSessionDataDelegate代理

002 每次请求的时候都到本地缓存获取对应的数据流大小 然后更新self.currentSize

003 对NSMutableURLRequest 的forHTTPHeaderField:进行处理

       NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

            //设置请求头

        NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentSize];

        [request setValue:range forHTTPHeaderField:@"Range"];

004 将下载数据存到本地缓存

在收到服务器响应的代理方法中 获取总容量,将输出流对应到本地缓存目录下

打开接收流 允许请求执行

 

在收到下载数据的代理方法中 将下载得到数据流写入到本地缓存的目录下

同时更新当前进度数据

 

 

代码如下:

//

//  ViewController.m

//  LearnDownloader

//

//  Created by maochengfang on 2020/10/21.

//

 

#import "ViewController.h"

#define kFileName @"124.mp4"

 

 

@interface ViewController ()<NSURLSessionDataDelegate>

@property (nonatomic, strong) NSOutputStream *stream;

@property (nonatomic, assign) NSInteger totalSize;

@property (nonatomic, assign) NSInteger currentSize;

@property (nonatomic, strong) NSURLSessionDataTask *downloadTask;

 

@property (nonatomic, strong) NSURLSession *session;

 

@end

 

@implementation ViewController

 

- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view.

    

    [self startDownLoad];

}

 

- (NSURLSession *)session{

    

    if(!_session){

        _session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];

    }

    

    return  _session;

}

- (NSURLSessionDataTask *)downloadTask{

    

    if(!_downloadTask){

        

        self.currentSize = [self getCurrentSize];

        

        NSURL *url = [NSURL URLWithString:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1603304688338&di=54159a129fde063b53e4b8e13d90c4e8&imgtype=0&src=http%3A%2F%2Ft9.baidu.com%2Fit%2Fu%3D1307125826%2C3433407105%26fm%3D79%26app%3D86%26f%3DJPEG%3Fw%3D5760%26h%3D3240"];

        

        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

        

    //设置请求头

        NSString *range = [NSString stringWithFormat:@"bytes=%zd-",self.currentSize];

        [request setValue:range forHTTPHeaderField:@"Range"];

        

        _downloadTask = [self.session dataTaskWithRequest:request];

        

    }

    

    return  _downloadTask;

}

 

 

- (void)startDownLoad{

    [self.downloadTask resume];

}

 

- (void)pauseDownLoad{

    [self.downloadTask suspend];

}

 

- (NSInteger)getCurrentSize{

    

    NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:kFileName];

    

    NSDictionary *fileDic = [[NSFileManager defaultManager] attributesOfItemAtPath:fullPath error:nil];

    

    return  [fileDic[@"NSFileSize"] integerValue];

}

 

 

//------------------------------

 

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(nonnull NSURLResponse *)response completionHandler:(nonnull void (^)(NSURLSessionResponseDisposition))completionHandler{

        

    self.totalSize = response.expectedContentLength + self.currentSize;

    

    NSString *fullPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:kFileName];

    self.stream = [[NSOutputStream alloc] initToFileAtPath:fullPath append:YES];

    

    [self.stream open];

    

    completionHandler(NSURLSessionResponseAllow);

}

 

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data{

    [self.stream write:data.bytes maxLength:data.length];

    self.currentSize += data.length;

}

 

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{

    [self.stream close];

    self.stream = nil;

}

 

- (void)dealloc{

    [self.session invalidateAndCancel];

}

@end

 

 

 

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页