本篇文章描述下如何实现一个多文件下载任务管理的示例。


基本思路:向下载任务进行模型封装

同时下载多个文件,将一个任务相关联的所有数据对象封装到一个模型对象中,方便管理


“下载任务”模型对象中的属性封装

1)下载任务的URL

@property(nonatomic,strong,readonly)NSURL*url;

2)下载任务的状态

typedefenum{NMDownloaderStateDownload,//正在下载NMDownloaderStateCompleted,//下载完成NMDownloaderStatePause,//暂停下载NMDownloaderStateFailed//下载失败}NMDownloaderState;@property(nonatomic,assign)NMDownloaderStatestate;

3)下载任务

@property(nonatomic,strong)NSURLSessionDownloadTask*dTask;

5)任务断点信息

@property(nonatomic,strong)NSData*resumeData;

6)下载进度信息

@property(nonatomic,strong)NSProgress*progress;


“下载任务”封装的方法

1)创建方法

+(NMDownloader*)downloaderWithUrl:(NSURL*)url{return[[NMNetworkMusicDownloaderalloc]initWithUrl:url];}-(instancetype)initWithUrl:(NSURL*)url{if(self=[superinit]){//使用NSURLSession创建下载任务并启动//传入progress并成为观察者}returnself;}

2)观察者响应方法

-(void)observeValueForKeyPath:(NSString*)keyPathofObject:(id)objectchange:(NSDictionary<NSString*,id>*)changecontext:(void*)context{if(object==self.progress&&[keyPathisEqualToString:@"fractionCompleted"]){NSNumber*new=change[@"new"];CGFloatn=new.doubleValue;//n即为当前的下载进度,可以通过代理将这个进度传递给UI元素以显示}}

3)下载控制器通过更改下载状态实现,重写setter方法

-(void)setState:(NMownloaderState)state{_state=state;if(_state==NMDownloaderStateDownload){//下载if(self.resumeData!=nil){//根据resumeData创建下载任务}[self.dTaskresume];//开始下载}elseif(_state==NMNetworkMusicDownloaderStatePause){//暂停[self.dTaskcancelByProducingResumeData:^(NSData*_NullableresumeData){//断点self.resumeData=resumeData;}];}//可以使用代理/通知将下载任务状态改变的信息通知到UI元素}


定义下载任务管理类

管理类应当是一个单例对象

1)管理所有的下载任务

/**下载任务数组*/@property(nonatomic,strong)NSArray*downloaderArray;

2)提供方法添加/删除下载任务

-(void)addDownloader:(NMNetworkMusicDownloader*)downloader;-(void)removeDownloader:(NMNetworkMusicDownloader*)downloader;


UI的显示的说明

由于下载任务的UI显示是需要实时更新的,将一个下载任务的显示封装成一个视图对象

更新的数据包括:下载进度、下载状态


"下载任务"模型对象,通过代理将下载进度、下载状态的变化 传递给这个视图对象,视图对象更新UI