(文章最后附有demo地址)
这两天事比较少,想想自己做开发以来,一直也没有接触过关于下载方面的东西,所以一直对这方面的了解比较少。SO⋯⋯这两天有个想法想写个封装的下载器。
为什么要写出来呢?
第一:这样做可以让自己更认真些
第二:分享本身就是一件很好的事吗?可以给刚刚接触这方面的新手朋友一个参考,同样也可以得到一些牛逼道友的指点。
这个图片没什么意义只是为了好看好了!粗粗的分割线代表着上面那段装b字段已经结束了,它的作用仅仅是让这篇文章的档次能够提到裤裆的位置。
下面我们要进入正题了,前方高能!请自觉系好安全带,带好自己的老婆孩子,七大姑八大姨……
下边我们要这一个下载器,我们要想一个问题,我们写的这个下载器要让它能干什么?
下载?!是的,你很聪明,知道下载器是用来下载,这点真的很难得。
然后呢?……
我们肯定都用过一些下载类的软件,比如迅雷?视频类的软件,比如爱奇艺?看小说类的软件,比如~我没用过,
用他们在下载的时候,不仅仅只是简单的将东西下载下来,在下载的同时还要让用户知道,下载速度,下载进度,甚至剩余时间。
那么问题来了,要想实现这些功能我们就必须在下载的时候拿到这些数据,做相应的处理,那么怎么获取呢?
重量级主角来 了 ~ NSUrlsession
什么你不知道这是什么鬼?请自觉直行左转,进百度点卡木,哪里可以找到答案,至少一万条相关信息。少一条来找我,不干什么,我写一条发上去,凑个整。少两条就不用找我了,两条太多写着累。
这个图片的作用也没什么意义只是为了更好看好了,到这里扯蛋的事就先停一停,说点正事,老扯你不疼吗??
在这里我就简单的对NSUrlsession做个介绍,NSUrlsession是苹果在ios7.0之后推出的一个用于网络请求的类,这个类相当强大,可以实现数据下载,数据请求,和数据上传等功能,当然它的使用还需要和他的老婆Task配合使用,两口子干活才能事半功倍吗。
Task又有细分好几种Task,至于哪几种,自行百度点卡木。在项目中NSURLSession的创建代码如下:
//下载相关
NSURLSession* session = [NSURLSessionsessionWithConfiguration:[NSURLSessionConfigurationdefaultSessionConfiguration]delegate:selfdelegateQueue:[[NSOperationQueuealloc]init]];
//创建流
NSOutputStream* stream = [NSOutputStreamoutputStreamToFileAtPath:HYFFileFullpath(url)append:YES];
//创建请求体
NSMutableURLRequest* request = [NSMutableURLRequestrequestWithURL:[NSURLURLWithString:url]];
//设置请求头
NSString* range = [NSStringstringWithFormat:@"byte=%zd-",HYFDownloadLength(url)];
[requestsetValue:rangeforHTTPHeaderField:@"Range"];
//创建datatask
NSURLSessionDataTask* task = [sessiondataTaskWithRequest:request];//讲请求体配置到任务中
NSUIntegertaskIdentifier =arc4random() % ((arc4random() %10000+arc4random() %10000));//产生一个随机数这里随便
[tasksetValue:@(taskIdentifier)forKey:@"taskIdentifier"];//为task的属性taskIdentifier赋值,用于唯一表示它
NSURLSession的数据接收,主要在它的代理中实现,三个代理方法。
- (void)URLSession:(NSURLSession*)session dataTask:(NSURLSessionDataTask*)dataTask didReceiveResponse:(NSHTTPURLResponse*)response completionHandler:(void(^)(NSURLSessionResponseDisposition))completionHandler{ }
这个方法用于接收响应,在这里可以获取到文件的总长度,通过判断可以自主控制是否开启下载,详情参考demo
- (void)URLSession:(NSURLSession*)session dataTask:(NSURLSessionDataTask*)dataTask didReceiveData:(NSData*)data{}
这个方法就是用于接收服务器返回的数据,可以对数据进行拼接,判断,计算等惭怍。下载的速度和和下载所剩余的时间就是在这个方法里计算所得。
- (void)URLSession:(NSURLSession*)session task:(NSURLSessionTask*)task didCompleteWithError:(NSError*)error{}
最后这个方法,就是就是通过错误码判断是否下载成功,或者失败,做相应的处理。
好了主角介绍完了,下面我们大体的介绍一下需要完成这个东西,主要用到了那些技术点。
第一个点:回调用到了 block和代理协议,在这个下载器中两者我都用了,block可以实现即在下载页,回调数据,代理可以实现开启下载页和下载载页分离回调所需数据,好吧我嘴笨,具体你参考demo。
在demo中总共定义了两个block一个用于回调,下载相关的参数,另一个用于回调下载的状态,一个枚举值
//枚举下载状态
typedefNS_ENUM(NSInteger,HYFDownloadState) {
HYFDownloadStateStart =0,//下载进行中
HYFDownloadStateSuspended,//下载暂停
HYFDownloadStateCompleted,//下载完成
HYFDownloadStateFailed,//下载失败
};
//定义回调的block
typedef void(^HYFDownloadProgressBlock)(CGFloatprogress,NSString*speed,NSString*remainingTime,NSString*writtenSize,NSString*totalSize);
typedef void(^HYFDownloadStateBlock)(HYFDownloadStatestate);
第二个点:就是本地存储,为什么要本地存储,当下载完成,或者下载中断了,或者程序被退出后,当程序被再次唤起时,下载应该是按原来没有完成的继续下载。对不?
这里本地存储我用的是,解裆_提裆。啊~呸,是解档归档。如果不会不熟悉不要怕,我也现学的。可参考demo。
路径操作我都把他们定义成了宏,具体可参考demo
第三点:就是目录操作,在苹果的沙河中有三个文件夹,你想把你下载的东西存哪里?沙盒中这三个文件夹都有自己特定存储的意义,不熟悉文件操作方面和沙盒存储的的可自行参考demo或者百度点卡木。
好了到这里就可以干活了,可以写你的下载器了,在这篇文章中,关于技术方面写的比较少,我知道我写了你也不看,也会自己去看demo,SO……我只把这篇文章的档次提到了裤裆的位置。
项目运行后的效果是这样的,界面没有搭,比较low,还存在很多问题,很多bug,有些功能还需要完善,问题那么来了,该怎样优化它呢?发挥你超能力变身的时刻到了!!!
好了,大的方向也就这些吧。demo中也给出了大量注释,可以自行参考,祝你好运。
如果你在看后有什么更好的想法,或者见解,请@我 iosyufeng@sina.com
demo地址 git传送https://github.com/YufengHu123/HYFDownloadManager.git
(请用电脑打开)。
最后请教一个问题,简书上不能发小的短视频插在文章里吗?????
网友评论