探討“iOS 多任務下載”

這是一個老掉牙的標題,從 iOS 入行到現在,你或許看過很多介紹下載功能的博客,光簡書上就已經有一大片了。但我還是要再寫一篇!我也看過很多這個主題的文章,也讀過很多人封裝的下載代碼,但沒看到過比較讓人滿意的。如果你也有這種感覺,不妨接著往下看,我表述一些我的觀點,希望與諸君共同探討這個話題,共同探索一個最優解。

用哪種技術方案?

  1. NSURLConnection: 如果要支持 iOS 7 以下的版本,NSURLConnection 肯定會用到,但現在還要支持 iOS 6 或以下系統的應該很少了。由于 NSURLSession 比 NSURLConnection 有天生的優勢,此方案后面不再考慮。
  2. NSURLSession: 從 iOS 7 開始被支持,功能比 NSURLConnection 更強大。
  3. AFNetworking: iOS 界久負盛名的網絡框架,內部實現也是基于 NSURLSession 或 NSURLConnection。

普通網絡請求用 AFNetworking,下載也可以用嗎?

就我之前查到的各種下載封裝來看,直接用 NSURLSession 實現的比較多,而用 AFNetworking 實現的很少。

先想一下為什么有那么多項目中網絡請求要用 AFNetworking ?答案很簡單:簡單唄,不用自己管 NSURLSession(或NSURLConnection)那一大堆代理方法了,直接處理 AFNetworking 提供的success & failure block回調就行了。

既然 AFNetworking 有這種好處,那我們再想,下載也可以直接用 AFNetworking 嗎?答案是可以!回顧一下 AFNetworking 中的兩個核心類:AFURLSessionManager 封裝了對 NSURLSession 的處理,尤其是將 NSURLSession 的那些代理方法都通過封裝轉換成了 AFNetworking 中簡單的 block 了;AFHTTPSessionManager 將常用的 HTTP 請求方法(GET、POST等)進行了封裝。

一起看下 AFURLSessionManager 類的兩個方法:

- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request
                                             progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock
                                          destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
                                    completionHandler:(nullable void (^)(NSURLResponse *response, NSURL * _Nullable filePath, NSError * _Nullable error))completionHandler;

- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData
                                                progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgressBlock
                                             destination:(nullable NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination
                                       completionHandler:(nullable void (^)(NSURLResponse *response, NSURL * _Nullable filePath, NSError * _Nullable error))completionHandler;

毫無疑問,通過 AFNetworking 實現下載功能會比直接使用 NSURLSession 簡單很多,在使用 AFNetworking 的項目中,使用 AFNetworking 實現下載功能是最佳的方案。

需要支持的功能

上面討論了實現的方案,這里再說說下載的封裝需要具備哪些“通用”的下載功能,適應各種各樣的下載需求呢?

  • 既然叫“多任務”下載,同時下載多個是必然需要的。
  • 再進一步,需要可以控制同時下載的數目。
  • 狀態更新,比如在 UITableViewCell 上更新下載進度、下載狀態等。
  • 再進一步,不能只在下載的界面觀察下載狀態,應該是所有關心下載狀態的地方都可以實時更新狀態的改變。
  • 后臺下載,現在下載的標配。
  • 其他細碎的需求,比如下載速度、是否允許蜂窩網絡、是否可以定制下載請求的請求頭等。
  • 在具備這些功能的基礎上,最重要的是需要使用簡單,最好像 AFNetworking 那么簡單,降低學習成本,這樣用的人才會爽。

我的實現

如果你需要一個如上所說的下載封裝來在自己的項目中實現多任務下載這樣的功能,可以嘗試一下我寫的 SODownloader,可以通過 CocoaPods 很方便的集成到自己項目中,還有其用法

雖然 SODownloader 已經在我自己的項目中“試用”了一年多了,但由于我個人能力的局限性,這依然不可能是一個最佳的方案。如果你也認同我的思路,認為可以創造出一個最佳方案,歡迎和我一起完善 SODownloader!

另外,好想感受被 Star 狂砸的感覺的說~

一起探討

我寫這篇博客表達我自己對下載功能的理解,拋磚引玉。如果閣下有不一樣的見解,歡迎提出,我們一起探討。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,232評論 4 61
  • Swift版本點擊這里歡迎加入QQ群交流: 594119878最新更新日期:18-09-17 About A cu...
    ylgwhyh閱讀 25,550評論 7 249
  • 創業是一場“重感冒”,會傳染。信不信由你,反正我信了。 今天群里有姐妹說了一句話,感動了很長時間,她說:“如果能感...
    茉莉大大閱讀 192評論 0 0
  • 我想記下那天和包老師和其夫人董莉,呂欣姐及老兄唐教主在青島相聚的美好時光。 多年以后,當回顧往事,不再用往事如煙來...
    無無行閱讀 504評論 0 2
  • 北風起了,自己要加一件冬衣 緋色的你,獨自一人 在感受著什么呢,盼你能察覺 今夜小雨紛紛,你在想什么呢 如果可以,...
    外向的孤獨患者97860閱讀 297評論 0 2