![]() ![]() 功能: -單個任務下載 -暫停下載任務 -取消下載任務 -斷點下載 -顯示下載進度及速度 -多任務下載 -分別控制各個任務 在現在移動互聯網的浪潮中,手機APP愈來愈依賴網絡通信來交互數據。今天咱們就來分享下如何經過使用NSURLSession這個Apple官方提供的網絡接口實現文件下載的思路。 NSURLSsession 先來介紹下NSURLSession這個接口。NSURLSession是蘋果在WWDC2013上推出的用於替代它的前輩NSURLConnection的。 與NSURLConnection相似,除了同名類NSURLSession,NSURLSession也是指一組相互依賴的類。NSURLSession包括與以前相同的組件,例如NSURLRequest, NSURLCache等。NSURLSession的不一樣之處在於,它把 NSURLConnection替換爲NSURLSession, NSURLSessionConfiguration,以及3個NSURLSessionTask的子類:NSURLSessionDataTask, NSURLSessionUploadTask, 和NSURLSessionDownloadTask。 與NSURLConnection相比,NSURLSession最直接的改善就是提供了配置每一個會話的緩存,協議,cookie和證書政策(credential policies),甚至跨應用程序共享它們的能力。這使得框架的網絡基礎架構和部分應用程序獨立工做,而不會互相干擾。每個NSURLSession對象都是根據一個NSURLSessionConfiguration初始化的,該NSURLSessionConfiguration指定了上面提到的政策,以及一系列爲了提升移動設備性能而專門添加的新選項。 NSURLSession的另外一重要組成部分是會話任務,它負責處理數據的加載,以及客戶端與服務器之間的文件和數據的上傳下載服務。NSURLSessionTask與NSURLConnection是及其類似的,由於它負責加載數據,而主要的區別在於,任務共享它們父類NSURLSession的共同委託(common delegate)。 NSURLSession支持如下三種會話模式: ![]() 一、默認會話模式(default):默認模式,基於磁盤緩存的持久化策略,使用用戶keychain中保存的證書進行認證受權。 二、瞬時會話模式(ephemeral):不儲存任何數據在磁盤中,全部數據都保存在RAM中,當會話結束後,緩存數據將被清空。 三、後臺會話模式(background):該模式相似於默認模式,只是將上傳和下載移至後臺處理,須要一個提供一個String用於標識後臺會話。 NSURLSession同時也提供了大量的配置選項: ![]() ![]() 配置完會話類型後,就能夠獲取NSURLSession對象了。獲取對象的方法有如下幾種: ![]() 一、sharedSession獲取的會話使用的是默認配置(default),全局共享的Cookies,Cache和證書。 二、使用構造器構造一個指定配置的會話對象。 三、 使用構造器構造一個指定配置對象,並指定代理及代理列隊。 獲取完會話對象後就該給對象一個會話任務了。在這裏是經過創建一個會話任務對象來實現佈置任務的。在一個會話中,NSURLSession支持三種會話任務: 一、數據任務(NSURLSessionDataTask) 使用NSData對象來發送和接收數據。數據任務能夠分片返回數據,也能夠經過完成處理器一次性返回數據。因爲數據任務不存儲數據到文件,因此不支持後臺會話。 ![]() 二、上傳任務(NSURLSessionUploadTask) 一般以文件的形式發送數據,支持後臺上傳。 ![]() 三、任務(NSURLSessionDownloadTask) 以文件的形式接收數據,當程序不運行時支持後臺下載 ![]() 得到任務對象後,就能夠對它進行以下操做: ![]() 經過對NSURLSession的簡單介紹,你們應該對其有了歌簡單的認識,接下就來介紹下如何實現本文開始階段所展現Demo的全部功能。 Demo詳解 先作一些準備工做: 建立一個用於存放下載數據信息的struct DownloadData ![]() 建立一個代理協議,以後會介紹它的用處 ![]() 接着咱們開始創建一個本身的DownloadTask類,用來實現下載DownloadData,並提供暫停任務、斷點下載、取消任務、實時更新下載進度及速度等功能: 咱們先來定義一些屬性, ![]() 其中, 代理是用於觸發以前協議中所定義的方法的, 數組和計時器涌來計算下載速度的, 下載任務id是爲了方便管理多個任務。 接着是構造器, ![]() 經過構造器咱們將從外部得到DownloadData,id及delegate。 完成了這些後,就是編寫下載方法了, ![]() 這裏將自身設置爲NSURLSession代理後,就須要在類中遵循NSURLSessionDownloadDelegate協議,並實現其方法。 在這裏我實現以下方法, ![]() ![]() 固然,在構造task時也可使用帶block的構造器,將task完成後所要執行的操做經過閉包的方式傳給task。這樣作的話在定義NSURLSession中就無需設置代理了。可是,不使用代理的方法是沒法獲取到下載任務的實時信息的,故要獲取下載進度及速度的話,仍是應該使用NSURLSession代理。 若是completionhandler 閉包和 didFinishDownloadingToURL 方法同時存在的話,優先執行completionhandler,並會忽略didFinishDownloadingToURL方法。 下面是實現實時速度更新的方法, ![]() 而後是暫停任務方法, ![]() 這裏要注意的是,cancelByProducingResumeData 生成的NSData中包含的並非以前所下載的數據,而是記錄下載產生的臨時文件的位置及下載到什麼進度的信息,因此並不會佔用很大的內存。 任務暫停後,將這次任務清空。 最後是取消任務方法, ![]() 清空記錄下載信息數據文件後,再次開始任務就不能繼續從以前斷開的位置繼續下載了。 以上就是DownloadTask類的所有內容了, 最後就是創建一個UI調用下DownloadTask,看看這個類在實際使用中的效果如何。 UI: ![]() 從0-5依次編號控件,包括1個progressView,2個label,3button,並把他們分別放入collection中,如圖: ![]() 定義一個taskCollection用於存放全部task,如圖: ![]() 初始化界面,並定義6個DownloadTask: ![]() 替3種button分別添加方法: ![]() 最後實現DownloadTaskDelegate代理方法,用於更新UI: ![]() |