iOS斷點(diǎn)+后臺(tái)下載
設(shè)計(jì)思路是根據(jù)寫一個(gè)通用控件的思路缓窜,iOS下載可以用的方式有很多管闷,像之前的URLConnection到現(xiàn)在的URLSession粥脚,本例用的是URLSession+URLSessionDownloadTask,斷點(diǎn)下載不止可以用這個(gè)DownloadTask包个,還可以用NSURLSessionDataTask,但是還要做到后臺(tái)下載的只有URLSessionDownloadTask
邏輯流程
1刷允、創(chuàng)建后臺(tái)session
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:identify];
[NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
2、實(shí)現(xiàn)session代理
//session下載中的回調(diào)
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didWriteData:(int64_t)bytesWritten
totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
//session下載完成后回調(diào)
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location
//sessiontask任務(wù)結(jié)束后回調(diào)碧囊,就算是后臺(tái)下載树灶,或是異常退出,當(dāng)重新打開app時(shí)糯而,上次的下載任務(wù)還是會(huì)走這個(gè)回調(diào)天通,所以通過這里來完成后臺(tái)下載,包括后臺(tái)中斷下載在進(jìn)入前臺(tái)恢復(fù)
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
3熄驼、開始下載
//主要是判斷有無之前的下載數(shù)據(jù)
if (model.cqResumeData) {
downloadTask = [self.session downloadTaskWithCorrectResumeData:model.cqResumeData];
}else{
downloadTask = [self.session downloadTaskWithURL:[NSURL URLWithString:model.cqDownloadUrl]];
}
封裝思路
使用一個(gè)單例來管理所有的downloadtask像寒,并且只實(shí)例化一個(gè)后臺(tái)session來管理,這樣方便管理回調(diào)事件瓜贾,為每一個(gè)請(qǐng)求創(chuàng)建一個(gè)downloadFileModel來管理下載狀態(tài)诺祸,緩存。
首先從使用者角度上看分析出只需要如下功能阐虚,并且使用者只需要提供一個(gè)URL
1序臂、獲取下載模型 2、開始下載 3实束、暫停下載 4奥秆、取消下載
下載管理單例類
//私有屬性
@property (nonatomic, strong) NSURLSession *session;
@property (nonatomic, strong) NSMutableDictionary *downloadTasks;
@property (nonatomic, strong) NSMutableDictionary *downloadModels;
//對(duì)外接口
+(instancetype)shareManager;//獲取單例
-(void)setUpSession;//初始化backgroundSession
-(DownloadFileModel *)getModelByUrl:(NSString *)url;
//下面幾個(gè)可以說對(duì)外,但其實(shí)還是對(duì)downloadModel開放的接口
-(void)startDownloadWithURL:(NSString *)url;
-(void)stopTaskWithUrl:(NSString *)url;
-(void)cancelTaskWithURL:(NSString *)url;
下載任務(wù)模型
@property(nonatomic,strong) NSString *cqDownloadUrl;
@property(nonatomic,readonly) NSString *cqDownloadFilePath;
@property(nonatomic,strong) NSString *cqSessionTaskId;
@property(nonatomic,strong) NSData *cqResumeData;
@property(nonatomic,assign) CGFloat cqProgress;
@property(nonatomic,assign) NSUInteger cqTotalLength;
@property(nonatomic,assign) NSUInteger cqCurrentDownloadLength;
@property(nonatomic,assign) DownloadType cqDownloadType;
-(instancetype)initWithUrl:(NSString *)url;
- (void)setCacheFile;
- (void)loadCacheFile;
- (void)checkDownload;
//用戶接口
@property(nonatomic,weak) id<NewDownloadFileDelegate> cqDelegate;
-(void)startDownloadTask;
-(void)stopDonwloadTask;
-(void)cancelDownloadTask;
使用方法:
1咸灿、 在appdelegate中調(diào)用[[DownloadFileManager shareManager]setUpSession];
初始化session构订,為了是獲取之前下載中斷的下載任務(wù),和緩存的任務(wù)模型
2避矢、 后面再需要下載的地方通過DownloadFileModel *model = [[DownloadFileManager shareManager]getModelByUrl:url];
獲取下載任務(wù)模型悼瘾,只能通過這種,獲取审胸,因?yàn)槿绻坝兄袛嗟娜蝿?wù)會(huì)通過這個(gè)方法重新獲取回來亥宿。
3、設(shè)置模型代理model.cqDelegate = self;
4砂沛、通過模型去執(zhí)行開始烫扼,暫停,取消操作
[model stopDonwloadTask];[model startDownloadTask];[model cancelDownloadTask];
5碍庵、通過代理方法監(jiān)聽模型下載狀態(tài)
-(void)downloadTaskModel:(DownloadFileModel *)taskModel StateChange:(DownloadType)type; -(void)downloadTaskModel:(DownloadFileModel *)taskModel Progress:(CGFloat)progress;
demo地址https://github.com/MartinOSix/DemoKit/tree/master/dOC/SingleFileDownload