前一阵项目中有了下载视频的需求,于是满心欢喜的去github上搜索文件下载工具类,结果略失望,竟然没有一个相当满意的。虽然AFNetworking中文件下载功能已经相当完善,但是我需要一些比如全部暂停,全部开始之类的管理的功能,于是就试着自己动手造了个*。
其实文件下载,从根本上说就是两种方式:NSURLConnection和NSURLSession。
首先一个文件加入到下载队列后可能会有如下5种状态:下载中,等待中,暂停中,下载完成,下载失败。
typedef NS_ENUM(NSInteger, FileDownloadState){
FileDownloadStateWaiting = 0,
FileDownloadStateDownloading = 1,
FileDownloadStateSuspending = 2,
FileDownloadStateFail = 3,
FileDownloadStateFinish = 4,
};
其次我希望在初始化下载管理类后能只调用一个方法就开始去进行文件下载,然后就等待接收回调方法了,于是
- (void)addDownloadWithFileId:(NSString *)fileId fileUrl:(NSString *)url directoryPath:(NSString *)directoryPath fileName:(NSString *)fileName;
接着,为了实现多个文件同时下载时的各种控制,我创建了如下诸多方法:
//点击等待项(-》立即下载/暂停/do nothing)
- (void)startDownloadWithFileId:(NSString *)fileId;
//点击下载项 -》暂停
- (void)suspendDownloadWithFileId:(NSString *)fileId;
//点击暂停项(-》立刻下载/添加到下载队列)
- (void)recoverDownloadWithFileId:(NSString *)fileId;
//点击失败项 -》添加到下载队列
- (void)restartDownloadWithFileId:(NSString *)fileId;
//取消下载,且删除文件,只适用于未下载完成状态,下载完成的直接根据路径删除即可
- (void)cancelDownloadWithFileId:(NSString *)fileId;
//暂停全部:下载的,等待的
- (void)suspendAllFilesDownload;
//恢复全部:暂停的,失败的
- (void)recoverAllFilesDownload;
//取消全部:下载的,等待的,暂停的,失败的
- (void)cancelAllFilesDownload;
为了知道各个文件的下载状态,有如下方法:
- (FileDownloadState)getFileDownloadStateWithFileId:(NSString *)fileId;
最后,对于下载过程中以及完成后的各种状态需要监测
/*
下载开始
*/
- (void)fileDownloadManagerStartDownload:(SCFileDownload *)download;
/*
得到响应,获得文件大小等
*/
- (void)fileDownloadManagerReceiveResponse:(SCFileDownload *)download FileSize:(uint64_t)totalLength;
/*
下载过程,更新进度
*/
- (void)fileDownloadManagerUpdateProgress:(SCFileDownload *)download didReceiveData:(uint64_t)receiveLength downloadSpeed:(NSString *)downloadSpeed;
/*
下载完成,包括成功和失败
*/
- (void)fileDownloadManagerFinishDownload:(SCFileDownload *)download success:(BOOL)downloadSuccess error:(NSError *)error;
@end
至于文件如何从网络获取,核心代码无非是调用如下几个方法:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
}
或者是如下几个方法:
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes{
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite{
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location{
}
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error{
}
更或者直接用AFNetworking也可以。
PS:项目完整版下载地址为:
基于NSURLConnection实现:
https://github.com/wangqi211/FileDownloadTool
基于NSURLSession实现:
https://github.com/wangqi211/FileDownloadManager