MCDownloadManager ios文件下载管理器Word格式.docx
- 文档编号:18234930
- 上传时间:2022-12-14
- 格式:DOCX
- 页数:19
- 大小:796.39KB
MCDownloadManager ios文件下载管理器Word格式.docx
《MCDownloadManager ios文件下载管理器Word格式.docx》由会员分享,可在线阅读,更多相关《MCDownloadManager ios文件下载管理器Word格式.docx(19页珍藏版)》请在冰豆网上搜索。
写一个下载器,一定需要一个对象来描述下载的文件。
在这个下载器中,我们使用MCDownloadReceipt。
既然是一个信息的载体,那么从设计角度来说,我们应该使用它来存储跟文件相关的内容,不应该让他完成其他更多的事情,比如说开始,暂停等等。
MCDownloadReceipt使用归档进行本地化存储。
核心下载使用NSURLSession实现,下边我们会介绍详情。
MCDownloadReceipt
MCDownloadReceipt的主要功能是用于记录下载信息。
即使下载未完成,也能在MCDownloadReceipt的filePath路径下找个这个文件。
我们先来看看暴露出来的头文件信息:
∙NSString*url
作为MCDownloadReceipt的唯一标识。
∙NSString*filePath
MCDownloadReceipt的文件索引。
∙NSString*filename
MCDownloadReceipt的文件名,命名规则为:
把url进行MD5编码后作为文件名,url中如果有后缀,就拼接后缀。
∙MCDownloadStatestate
MCDownloadReceipt的状态
oMCDownloadStateNone,
oMCDownloadStateWillResume,
oMCDownloadStateDownloading,
oMCDownloadStateSuspened,
oMCDownloadStateCompleted,
oMCDownloadStateFailed
∙longlongtotalBytesWritten
总共写入的数据的大小
∙totalBytesExpectedToWrite
文件总大小
∙NSOutputStream*stream
用于把数据写入到路径中
1.获取filename
通常我们把文件的下载URL进行MD5编码后在拼接上后缀名来作为本地文件的名称。
把一个字符串转为MD5字符串:
staticNSString*getMD5String(NSString*str){
if(str==nil)returnnil;
constchar*cstring=str.UTF8String;
unsignedcharbytes[CC_MD5_DIGEST_LENGTH];
CC_MD5(cstring,(CC_LONG)strlen(cstring),bytes);
NSMutableString*md5String=[NSMutableStringstring];
for(inti=0;
i<
CC_MD5_DIGEST_LENGTH;
i++){
[md5StringappendFormat:
@"
%02x"
bytes[i]];
}
returnmd5String;
}
拼接名称:
-(NSString*)filename{
if(_filename==nil){
NSString*pathExtension=self.url.pathExtension;
if(pathExtension.length){
_filename=[NSStringstringWithFormat:
%@.%@"
getMD5String(self.url),pathExtension];
}else{
_filename=getMD5String(self.url);
return_filename;
2.获取filePath
首先我们要获取一个缓存的路径:
NSString*constMCDownloadCacheFolderName=@"
MCDownloadCache"
;
staticNSString*cacheFolder(){
NSFileManager*filemgr=[NSFileManagerdefaultManager];
staticNSString*cacheFolder;
staticdispatch_once_tonceToken;
dispatch_once(&
onceToken,^{
if(!
cacheFolder){
NSString*cacheDir=NSHomeDirectory();
cacheFolder=[cacheDirstringByAppendingPathComponent:
MCDownloadCacheFolderName];
NSError*error=nil;
if(!
[filemgrcreateDirectoryAtPath:
cacheFolderwithIntermediateDirectories:
YESattributes:
nilerror:
&
error]){
NSLog(@"
Failedtocreatecachedirectoryat%@"
cacheFolder);
cacheFolder=nil;
});
returncacheFolder;
拼接路径和文件名:
-(NSString*)filePath{
NSString*path=[cacheFolder()stringByAppendingPathComponent:
self.filename];
[pathisEqualToString:
_filePath]){
if(_filePath&
!
[[NSFileManagerdefaultManager]fileExistsAtPath:
_filePath]){
NSString*dir=[_filePathstringByDeletingLastPathComponent];
[[NSFileManagerdefaultManager]createDirectoryAtPath:
dirwithIntermediateDirectories:
nil];
_filePath=path;
return_filePath;
3.获取文件的大小
获取某个路径下文件的大小:
staticunsignedlonglongfileSizeForPath(NSString*path){
signedlonglongfileSize=0;
NSFileManager*fileManager=[NSFileManagerdefaultManager];
if([fileManagerfileExistsAtPath:
path]){
NSDictionary*fileDict=[fileManagerattributesOfItemAtPath:
patherror:
error];
error&
fileDict){
fileSize=[fileDictfileSize];
returnfileSize;
获取本对象的文件大小:
-(longlong)totalBytesWritten{
returnfileSizeForPath(self.filePath);
4.初始化stream
-(NSOutputStream*)stream
{
if(_stream==nil){
_stream=[NSOutputStreamoutputStreamToFileAtPath:
self.filePathappend:
YES];
return_stream;
5.设置progress
-(NSProgress*)progress{
if(_progress==nil){
_progress=[[NSProgressalloc]initWithParent:
niluserInfo:
_progress.totalUnitCount=self.totalBytesExpectedToWrite;
_pletedUnitCount=self.totalBytesWritten;
return_progress;
6.初始化和归档
-(instancetype)initWithURL:
(NSString*)url{
if(self=[selfinit]){
self.url=url;
self.totalBytesExpectedToWrite=1;
returnself;
#pragmamark-NSCoding
-(void)encodeWithCoder:
(NSCoder*)aCoder
[aCoderencodeObject:
self.urlforKey:
NSStringFromSelector(@selector(url))];
self.filePathforKey:
NSStringFromSelector(@selector(filePath))];
@(self.state)forKey:
NSStringFromSelector(@selector(state))];
self.filenameforKey:
NSStringFromSelector(@selector(filename))];
@(self.totalBytesWritten)forKey:
NSStringFromSelector(@selector(totalBytesWritten))];
@(self.totalBytesExpectedToWrite)forKey:
NSStringFromSelector(@selector(totalBytesExpectedToWrite))];
-(id)initWithCoder:
(NSCoder*)aDecoder
self=[superinit];
if(self){
self.url=[aDecoderdecodeObjectForKey:
self.filePath=[aDecoderdecodeObjectForKey:
self.state=[[aDecoderdecodeObjectOfClass:
[NSNumberclass]forKey:
NSStringFromSelector(@selector(state))]unsignedIntegerValue];
self.filename=[aDecoderdecodeObjectForKey:
self.totalBytesWritten=[[aDecoderdecodeObjectOfClass:
NSStringFromSelector(@selector(totalBytesWritten))]unsignedIntegerValue];
self.totalBytesExpectedToWrite=[[aDecoderdecodeObjectOfClass:
NSStringFromSelector(@selector(totalBytesExpectedToWrite))]unsignedIntegerValue];
MCDownloadControlDelegate
是这样的,如果我们要给某个对象扩展一类的功能或者方法,那么我们最好使用协议。
在AFNetworking的AFURLResponseSerialization和AFURLRequestSerialization就是最好的例子。
@protocolMCDownloadControlDelegate<
NSObject>
-(void)resumeWithURL:
(NSString*_Nonnull)url;
-(void)resumeWithDownloadReceipt:
(MCDownloadReceipt*_Nonnull)receipt;
-(void)suspendWithURL:
-(void)suspendWithDownloadReceipt:
-(void)removeWithURL:
-(void)removeWithDownloadReceipt:
@end
实现部分:
#pragmamark-MCDownloadControlDelegate
if(url==nil)return;
MCDownloadReceipt*receipt=[selfdownloadReceiptForURL:
url];
[selfresumeWithDownloadReceipt:
receipt];
(MCDownloadReceipt*)receipt{
if([selfisActiveRequestCountBelowMaximumLimit]){
[selfstartTask:
self.tasks[receipt.url]];
}else{
receipt.state=MCDownloadStateWillResume;
[selfsaveReceipts:
self.allDownloadReceipts];
[selfenqueueTask:
-(void)suspendAll{
for(NSURLSessionDownloadTask*taskinself.queuedTasks){
[tasksuspend];
task.taskDescription];
receipt.state=MCDownloadStateSuspened;
-(void)suspendWithURL:
[selfsuspendWithDownloadReceipt:
[selfupdateReceiptWithURL:
receipt.urlstate:
MCDownloadStateSuspened];
NSURLSessionDataTask*task=self.tasks[receipt.url];
if(task){
[selfremoveWithDownloadReceipt:
[taskcancel];
[self.queuedTasksremoveObject:
task];
[selfsafelyRemoveTaskWithURLIdentifier:
receipt.url];
[self.allDownloadReceiptsremoveObject:
[fileManagerremoveItemAtPath:
receipt.filePatherror:
MCDownloadManager
初始化MCDownloadManager跟AFNetworking中AFImageDownloader的初始化很像,做一些网络配置。
参数配置。
我们规定下载任务的创建都放在一个专有的同步队列中完成。
我们还要监听applicationWillTerminate
和
applicationDidReceiveMemoryWarning这两个通知,并在通知方法中,暂停多有的下载任务。
初始化示例代码:
+(NSURLSessionConfiguration*)defaultURLSessionConfiguration{
NSURLSessionConfiguration*configuration=[NSURLSessionConfigurationdefaultSessionConfiguration];
configuration.HTTPShouldSetCookies=YES;
configuration.HTTPShouldUsePipelining=NO;
configuration.requestCachePolicy=NSURLRequestUseProtocolCachePolicy;
configuration.allowsCellularAccess=YES;
configuration.timeoutIntervalForRequest=60.0;
returnconfiguration;
-(instancetype)init{
NSURLSessionConfiguration*defaultConfiguration=[self.classdefaultURLSessionConfiguration];
NSOperationQueue*queue=[[NSOperationQueuealloc]init];
queue.maxConcurrentOperationCount=1;
NSURLSession*session=[NSURLSessionsessionWithConfiguration:
defaultConfigurationdelegate:
selfdelegateQueue:
queue];
return[selfinitWithSession:
session
downloadPrioritization:
MCDownloadPrioritizationFIFO
maximumActiveDownloads:
4];
-(instancetype)initWithSession:
(NSURLSession*)sessiondownloadPrioritization:
(MCDownloadPrioritization)downloadPrioritizationmaximumActiveDownloads:
(NSInteger)maximumActiveDownloads{
if(self=[superinit]){
self.session=
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- MCDownloadManager ios文件下载管理器 ios 文件 下载 管理器