NSURLSession實現(xiàn)下載功能

最近做云盤項目,必不可少的就是下載上傳,這里先介紹下載類的實現(xiàn),不過沒有用多線程下載,還有很多不足的地方請大家指出更正。

@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數(shù)據(jù)庫,對于線程要求很高就不再深究,有時間在回過頭來處理這個問題。

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

}

return _session;

}

//開始下載的方法

/*

*? 從0開始下載

*/

- (void)startDownload{

NSURL *url = self.path.jq_URL;//這里用了分類,實際上就是將path轉(zhuǎn)URL,這里的Path就是文件的下載路徑

//創(chuàng)建請求

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

//下載請求的方式,這個根據(jù)情況而定

[request setHTTPMethod:@"POST"];

//創(chuàng)建任務,這個task是因為會涉及到暫停,斷點續(xù)傳之類的要求

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

//開始任務

[self.downloadTask resume];

}

/*

*? 暫停下載

*/

- (void)pause{

MJWeakSelf//這個是MJRefresh的weakSelf的宏定義

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

//resumeData:包含了繼續(xù)下載的開始位置和下載的url

//斷點續(xù)傳不僅客戶端要做,還需要服務端進行相應的適配才行。

weakSelf.resumeData = resumeData;

//置空task,resume的時候重新創(chuàng)建

weakSelf.downloadTask = nil;

}];

}

/*

*? 恢復下載

*/

- (void)resume{

//傳入暫停下載返回的數(shù)據(jù)

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

//開始恢復下載

[self.downloadTask resume];

//清空上次返回數(shù)據(jù)

self.resumeData = nil;

}

//到這里已經(jīng)實現(xiàn)了基本的下載需求,不過對于項目肯定需要監(jiān)聽進度及其他一系列東西,這里要求我們滿足NSURLSessionDownloadDelegate協(xié)議,代理在config的時候已經(jīng)設置了

/**

*? 下載完畢會調(diào)用

*

*? @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];

//關(guān)閉定時器,這個定時器是用來計算每秒的下載速度

[self.timer invalidate];

}

/**

*? 每次寫入沙盒完畢調(diào)用

*? 在這里面監(jiā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)介紹的很詳細,具體要怎么操作根據(jù)實際需求做就好

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;//每秒清零一次

}

/**

*? 恢復下載后調(diào)用,

*/

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

//根據(jù)實際需求,在暫停后恢復下載可以做一定操作。

}

//結(jié)束介紹,歡迎大家提出意見,給予更新。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容