(文章最后附有demo地址)
? ? ? 這兩天事比較少喇完,想想自己做開發(fā)以來呵曹,一直也沒有接觸過關(guān)于下載方面的東西,所以一直對這方面的了解比較少何暮。SO??這兩天有個想法想寫個封裝的下載器奄喂。
?為什么要寫出來呢?
? ?第一:這樣做可以讓自己更認(rèn)真些
? ? 第二:分享本身就是一件很好的事嗎海洼?可以給剛剛接觸這方面的新手朋友一個參考跨新,同樣也可以得到一些牛逼道友的指點。
? 好了坏逢!粗粗的分割線代表著上面那段裝b字段已經(jīng)結(jié)束了域帐,它的作用僅僅是讓這篇文章的檔次能夠提到褲襠的位置。
? ? 下面我們要進(jìn)入正題了是整,前方高能肖揣!請自覺系好安全帶,帶好自己的老婆孩子浮入,七大姑八大姨……
? ? ?下邊我們要這一個下載器龙优,我們要想一個問題,我們寫的這個下載器要讓它能干什么事秀?
? ? ? ?下載彤断?!是的易迹,你很聰明宰衙,知道下載器是用來下載,這點真的很難得睹欲。
? ? ? ?然后呢供炼?……
? ? ? ?我們肯定都用過一些下載類的軟件,比如迅雷窘疮?視頻類的軟件袋哼,比如愛奇藝?看小說類的軟件考余,比如~我沒用過先嬉,
? ? ? 用他們在下載的時候,不僅僅只是簡單的將東西下載下來楚堤,在下載的同時還要讓用戶知道疫蔓,下載速度,下載進(jìn)度身冬,甚至剩余時間衅胀。
? ? ?那么問題來了,要想實現(xiàn)這些功能我們就必須在下載的時候拿到這些數(shù)據(jù)酥筝,做相應(yīng)的處理滚躯,那么怎么獲取呢?
? ? 重量級主角來 了 ?~ ? ? ? NSUrlsession
? ? ?什么你不知道這是什么鬼?請自覺直行左轉(zhuǎn)掸掏,進(jìn)百度點卡木茁影,哪里可以找到答案,至少一萬條相關(guān)信息丧凤。少一條來找我募闲,不干什么,我寫一條發(fā)上去愿待,湊個整浩螺。少兩條就不用找我了,兩條太多寫著累仍侥。
?好了要出,到這里扯蛋的事就先停一停,說點正事农渊,老扯你不疼嗎患蹂??
? ?在這里我就簡單的對NSUrlsession做個介紹腿时,NSUrlsession是蘋果在ios7.0之后推出的一個用于網(wǎng)絡(luò)請求的類况脆,這個類相當(dāng)強大,可以實現(xiàn)數(shù)據(jù)下載批糟,數(shù)據(jù)請求格了,和數(shù)據(jù)上傳等功能,當(dāng)然它的使用還需要和他的老婆Task配合使用徽鼎,兩口子干活才能事半功倍嗎盛末。
? Task又有細(xì)分好幾種Task,至于哪幾種否淤,自行百度點卡木悄但。在項目中NSURLSession的創(chuàng)建代碼如下:
//下載相關(guān)
NSURLSession* session = [NSURLSessionsessionWithConfiguration:[NSURLSessionConfigurationdefaultSessionConfiguration]delegate:selfdelegateQueue:[[NSOperationQueuealloc]init]];
//創(chuàng)建流
NSOutputStream* stream = [NSOutputStreamoutputStreamToFileAtPath:HYFFileFullpath(url)append:YES];
//創(chuàng)建請求體
NSMutableURLRequest* request = [NSMutableURLRequestrequestWithURL:[NSURLURLWithString:url]];
//設(shè)置請求頭
NSString* range = [NSStringstringWithFormat:@"byte=%zd-",HYFDownloadLength(url)];
[requestsetValue:rangeforHTTPHeaderField:@"Range"];
//創(chuàng)建datatask
NSURLSessionDataTask* task = [sessiondataTaskWithRequest:request];//講請求體配置到任務(wù)中
NSUIntegertaskIdentifier =arc4random() % ((arc4random() %10000+arc4random() %10000));//產(chǎn)生一個隨機數(shù)這里隨便
[tasksetValue:@(taskIdentifier)forKey:@"taskIdentifier"];//為task的屬性taskIdentifier賦值,用于唯一表示它
NSURLSession的數(shù)據(jù)接收石抡,主要在它的代理中實現(xiàn)檐嚣,三個代理方法。
- (void)URLSession:(NSURLSession*)session dataTask:(NSURLSessionDataTask*)dataTask didReceiveResponse:(NSHTTPURLResponse*)response completionHandler:(void(^)(NSURLSessionResponseDisposition))completionHandler{ ?}
這個方法用于接收響應(yīng)啰扛,在這里可以獲取到文件的總長度嚎京,通過判斷可以自主控制是否開啟下載,詳情參考demo
- (void)URLSession:(NSURLSession*)session dataTask:(NSURLSessionDataTask*)dataTask didReceiveData:(NSData*)data{}
這個方法就是用于接收服務(wù)器返回的數(shù)據(jù)隐解,可以對數(shù)據(jù)進(jìn)行拼接鞍帝,判斷,計算等慚怍煞茫。下載的速度和和下載所剩余的時間就是在這個方法里計算所得帕涌。
- (void)URLSession:(NSURLSession*)session task:(NSURLSessionTask*)task didCompleteWithError:(NSError*)error{}
最后這個方法摄凡,就是就是通過錯誤碼判斷是否下載成功,或者失敗蚓曼,做相應(yīng)的處理亲澡。
? ?好了主角介紹完了,下面我們大體的介紹一下需要完成這個東西辟躏,主要用到了那些技術(shù)點谷扣。
第一個點:回調(diào)用到了 block和代理協(xié)議,在這個下載器中兩者我都用了捎琐,block可以實現(xiàn)即在下載頁,回調(diào)數(shù)據(jù)裹匙,代理可以實現(xiàn)開啟下載頁和下載載頁分離回調(diào)所需數(shù)據(jù)瑞凑,好吧我嘴笨,具體你參考demo概页。
在demo中總共定義了兩個block一個用于回調(diào)籽御,下載相關(guān)的參數(shù),另一個用于回調(diào)下載的狀態(tài)惰匙,一個枚舉值
//枚舉下載狀態(tài)
typedefNS_ENUM(NSInteger,HYFDownloadState) {
HYFDownloadStateStart =0,//下載進(jìn)行中
HYFDownloadStateSuspended,//下載暫停
HYFDownloadStateCompleted,//下載完成
HYFDownloadStateFailed,//下載失敗
};
//定義回調(diào)的block
typedef void(^HYFDownloadProgressBlock)(CGFloatprogress,NSString*speed,NSString*remainingTime,NSString*writtenSize,NSString*totalSize);
typedef void(^HYFDownloadStateBlock)(HYFDownloadStatestate);
第二個點:就是本地存儲技掏,為什么要本地存儲,當(dāng)下載完成项鬼,或者下載中斷了哑梳,或者程序被退出后,當(dāng)程序被再次喚起時绘盟,下載應(yīng)該是按原來沒有完成的繼續(xù)下載鸠真。對不?
這里本地存儲我用的是龄毡,解襠_提襠吠卷。啊~呸,是解檔歸檔沦零。如果不會不熟悉不要怕祭隔,我也現(xiàn)學(xué)的÷凡伲可參考demo疾渴。
路徑操作我都把他們定義成了宏,具體可參考demo
第三點:就是目錄操作寻拂,在蘋果的沙河中有三個文件夾程奠,你想把你下載的東西存哪里?沙盒中這三個文件夾都有自己特定存儲的意義祭钉,不熟悉文件操作方面和沙盒存儲的的可自行參考demo或者百度點卡木瞄沙。
好了到這里就可以干活了,可以寫你的下載器了,在這篇文章中距境,關(guān)于技術(shù)方面寫的比較少申尼,我知道我寫了你也不看,也會自己去看demo垫桂,SO……我只把這篇文章的檔次提到了褲襠的位置师幕。
項目運行后的效果是這樣的,界面沒有搭诬滩,比較low霹粥,還存在很多問題,很多bug疼鸟,有些功能還需要完善后控,問題那么來了,該怎樣優(yōu)化它呢空镜?發(fā)揮你超能力變身的時刻到了:铺浴!吴攒!
好了张抄,大的方向也就這些吧。demo中也給出了大量注釋洼怔,可以自行參考署惯,祝你好運。
?如果你在看后有什么更好的想法茴厉,或者見解泽台,請@我 iosyufeng@sina.com
demo地址? git傳送https://github.com/YufengHu123/HYFDownloadManager.git
(請用電腦打開)。
最后請教一個問題矾缓,簡書上不能發(fā)小的短視頻插在文章里嗎怀酷??嗜闻?蜕依??