最近做云盤項(xiàng)目,必不可少的就是下載上傳详幽,這里先介紹下載類的實(shí)現(xiàn)筛欢,不過沒有用多線程下載浸锨,還有很多不足的地方請(qǐng)大家指出更正。
@property (nonatomic, strong) NSURLSessionDownloadTask* downloadTask;
/**
*? resumeData記錄下載位置
*/
@property (nonatomic, strong) NSData* resumeData;
@property (nonatomic, strong) NSURLSession* session;//SESSION對(duì)象是肯定要有的
對(duì)session就是懶加載
- (NSURLSession *)session{
if (!_session) {
NSURLSessionConfiguration *cfg = [NSURLSessionConfiguration defaultSessionConfiguration];
//這里的queue其實(shí)還可以進(jìn)一步細(xì)化版姑,不過項(xiàng)目很趕就沒做了柱搜,再加上使用了realm數(shù)據(jù)庫(kù),對(duì)于線程要求很高就不再深究剥险,有時(shí)間在回過頭來處理這個(gè)問題聪蘸。
_session = [NSURLSession sessionWithConfiguration:cfg delegate:self delegateQueue:[NSOperationQueue mainQueue]]
}
return _session;
}
//開始下載的方法
/*
*? 從0開始下載
*/
- (void)startDownload{
NSURL *url = self.path.jq_URL;//這里用了分類,實(shí)際上就是將path轉(zhuǎn)URL表制,這里的Path就是文件的下載路徑
//創(chuàng)建請(qǐng)求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//下載請(qǐng)求的方式健爬,這個(gè)根據(jù)情況而定
[request setHTTPMethod:@"POST"];
//創(chuàng)建任務(wù),這個(gè)task是因?yàn)闀?huì)涉及到暫停夫凸,斷點(diǎn)續(xù)傳之類的要求
self.downloadTask = [self.session downloadTaskWithRequest:request];
//開始任務(wù)
[self.downloadTask resume];
}
/*
*? 暫停下載
*/
- (void)pause{
MJWeakSelf//這個(gè)是MJRefresh的weakSelf的宏定義
[self.downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) {
//resumeData:包含了繼續(xù)下載的開始位置和下載的url
//斷點(diǎn)續(xù)傳不僅客戶端要做浑劳,還需要服務(wù)端進(jìn)行相應(yīng)的適配才行阱持。
weakSelf.resumeData = resumeData;
//置空task夭拌,resume的時(shí)候重新創(chuàng)建
weakSelf.downloadTask = nil;
}];
}
/*
*? 恢復(fù)下載
*/
- (void)resume{
//傳入暫停下載返回的數(shù)據(jù)
self.downloadTask = [self.session downloadTaskWithResumeData:self.resumeData];
//開始恢復(fù)下載
[self.downloadTask resume];
//清空上次返回?cái)?shù)據(jù)
self.resumeData = nil;
}
//到這里已經(jīng)實(shí)現(xiàn)了基本的下載需求,不過對(duì)于項(xiàng)目肯定需要監(jiān)聽進(jìn)度及其他一系列東西衷咽,這里要求我們滿足NSURLSessionDownloadDelegate協(xié)議鸽扁,代理在config的時(shí)候已經(jīng)設(shè)置了
/**
*? 下載完畢會(huì)調(diào)用
*
*? @param location? ? 文件臨時(shí)地址
*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
//保存至cache,方便清楚緩存
NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
// response.suggestedFilename : 建議使用的文件名镶骗,一般跟服務(wù)器端的文件名一致
NSString *file = [caches stringByAppendingPathComponent:downloadTask.response.suggestedFilename];
// 將臨時(shí)文件剪切或者復(fù)制Caches文件夾
NSFileManager *mgr = [NSFileManager defaultManager];
// AtPath : 剪切前的文件路徑
// ToPath : 剪切后的文件路徑
[mgr moveItemAtPath:location.path toPath:file error:nil];
//關(guān)閉定時(shí)器,這個(gè)定時(shí)器是用來計(jì)算每秒的下載速度
[self.timer invalidate];
}
/**
*? 每次寫入沙盒完畢調(diào)用
*? 在這里面監(jiān)聽下載進(jìn)度桶现,totalBytesWritten/totalBytesExpectedToWrite
*
*? @param bytesWritten? ? ? ? ? ? ? 這次寫入的大小
*? @param totalBytesWritten? ? ? ? 已經(jīng)寫入沙盒的大小
*? @param totalBytesExpectedToWrite 文件總大小
*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
//建議判斷是否存在同名文件,方法不在列舉
參數(shù)說明已經(jīng)介紹的很詳細(xì)鼎姊,具體要怎么操作根據(jù)實(shí)際需求做就好
self.spead += bytesWritten;//這里將開啟定時(shí)器骡和,計(jì)算速度
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;//每秒清零一次
}
/**
*? 恢復(fù)下載后調(diào)用,
*/
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{
//根據(jù)實(shí)際需求相寇,在暫停后恢復(fù)下載可以做一定操作慰于。
}
//結(jié)束介紹,歡迎大家提出意見唤衫,給予更新婆赠。