NSURLSession实现下载功能

最近做云盘项目,必不可少的就是下载上传,这里先介绍下载类的实现,不过没有用多线程下载,还有很多不足的地方请大家指出更正。

@property (nonatomic, strong) NSURLSessionDownloadTask* downloadTask;

/**

*  resumeData记录下载位置

*/

@property (nonatomic, strong) NSData* resumeData;

@property (nonatomic, strong) NSURLSession* session;//SESSION对象是肯定要有的

对session就是懒加载

- (NSURLSession *)session{

if (!_session) {

NSURLSessionConfiguration *cfg = [NSURLSessionConfiguration defaultSessionConfiguration];

//这里的queue其实还可以进一步细化,不过项目很赶就没做了,再加上使用了realm数据库,对于线程要求很高就不再深究,有时间在回过头来处理这个问题。

_session = [NSURLSession sessionWithConfiguration:cfg delegate:self delegateQueue:[NSOperationQueue mainQueue]]

}

return _session;

}

//开始下载的方法

/*

*  从0开始下载

*/

- (void)startDownload{

NSURL *url = self.path.jq_URL;//这里用了分类,实际上就是将path转URL,这里的Path就是文件的下载路径

//创建请求

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

//下载请求的方式,这个根据情况而定

[request setHTTPMethod:@"POST"];

//创建任务,这个task是因为会涉及到暂停,断点续传之类的要求

self.downloadTask = [self.session downloadTaskWithRequest:request];

//开始任务

[self.downloadTask resume];

}

/*

*  暂停下载

*/

- (void)pause{

MJWeakSelf//这个是MJRefresh的weakSelf的宏定义

[self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {

//resumeData:包含了继续下载的开始位置和下载的url

//断点续传不仅客户端要做,还需要服务端进行相应的适配才行。

weakSelf.resumeData = resumeData;

//置空task,resume的时候重新创建

weakSelf.downloadTask = nil;

}];

}

/*

*  恢复下载

*/

- (void)resume{

//传入暂停下载返回的数据

self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData];

//开始恢复下载

[self.downloadTask resume];

//清空上次返回数据

self.resumeData = nil;

}

//到这里已经实现了基本的下载需求,不过对于项目肯定需要监听进度及其他一系列东西,这里要求我们满足NSURLSessionDownloadDelegate协议,代理在config的时候已经设置了

/**

*  下载完毕会调用

*

*  @param location    文件临时地址

*/

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{

//保存至cache,方便清楚缓存

NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];

// response.suggestedFilename : 建议使用的文件名,一般跟服务器端的文件名一致

NSString *file = [caches stringByAppendingPathComponent:downloadTask.response.suggestedFilename];

// 将临时文件剪切或者复制Caches文件夹

NSFileManager *mgr = [NSFileManager defaultManager];

// AtPath : 剪切前的文件路径

// ToPath : 剪切后的文件路径

[mgr moveItemAtPath:location.path toPath:file error:nil];

//关闭定时器,这个定时器是用来计算每秒的下载速度

[self.timer invalidate];

}

/**

*  每次写入沙盒完毕调用

*  在这里面监听下载进度,totalBytesWritten/totalBytesExpectedToWrite

*

*  @param bytesWritten              这次写入的大小

*  @param totalBytesWritten        已经写入沙盒的大小

*  @param totalBytesExpectedToWrite 文件总大小

*/

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

//建议判断是否存在同名文件,方法不在列举

参数说明已经介绍的很详细,具体要怎么操作根据实际需求做就好

self.spead += bytesWritten;//这里将开启定时器,计算速度

if (!self.isBegin) {

self.timer = [NSTimer timerWithTimeInterval:1 target:self selector:@selector(calculateSpead) userInfo:nil repeats:YES];

[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:(NSRunLoopCommonModes)];

self.isBegin = YES;

}

}

- (void)calculateSpead{

NSLog(@"%@",self.spead);

self.spead = 0;//每秒清零一次

}

/**

*  恢复下载后调用,

*/

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{

//根据实际需求,在暂停后恢复下载可以做一定操作。

}

//结束介绍,欢迎大家提出意见,给予更新。

你可能感兴趣的:(NSURLSession实现下载功能)