NSURLSession下載與緩存

NSURLSession下載與緩存

iOS9要求網絡請求需要使用NSURLSession,那么本篇文章
就使用NSURLsession來實現視頻的下載,圖片的下載、取消下載、恢復下
載和緩存功能,期望與大家一起學習。

  • NSURLSessionConfiguration(參數配置類)

    NSURLSession狀態同時對應著多個連接,不像之前使用共享的一個全局狀態。會話是通過工廠方法(類方法)來創建對象
    NSURLSessionConfiguration

    總共有三種會話:

    1.defaultSessionConfiguration 默認的,進程內會話

    2.ephemeralSessionConfiguration短暫的(內
    存),進程內會話

3.backgroundSessionConfigurationWithIdentifier后臺會話

  • 相關屬性

    //后臺任務的標識符
    
    @property (nullable, readonly, copy) NSString *id entifier;
    
    //緩存的策略
    
    @property NSURLRequestCachePolicy requestCachePolicy;
    
    //請求超時時長
    
    @property NSTimeInterval timeoutIntervalForRequest;
    
    //網絡服務類型
    
    @property NSURLRequestNetworkServiceType networkServiceType;
    
    //是否在非無線的情況下請求網絡
    
    @property BOOL allowsCellularAccess;
    

手動下載視頻

  • 步驟:

    • 在Info.plist中添加NSAppTransportSecurity類型Dictionary。
      在NSAppTransportSecurity下添加NSAllowsArbitraryLoads類型Boolean,值設為YES;

    • 在工程內引入AVFoundation框架,并在相關類引入AVKit、AVFoundation頭文件;

    • 遵守NSURLSessionDelegate,NSURLSessionDownloadDelegate協議;

    • 準備一個MP4格式的url,進行下載;

    • 將下載完成的視頻資源存入本地,并進行播放。

  • 聲明相關屬性

 //下載任務  
 @property (nonatomic, strong)NSURLSessionDownloadTask *downTask;  
      
 //網絡會話  
 @property (nonatomic, strong)NSURLSession * downLoadSession;
  • 配置相關參數并下載
    //參數設置類  簡單的網絡下載使用             
      defaultSessionConfiguration即可
    NSURLSessionConfiguration          *sessionConfig =        
    [NSURLSessionConfiguration
    defaultSessionConfiguration];
    
     //創建網絡會話  
     self.downLoadSession = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:[NSOperationQueue new]];
    
    
     //數據請求  
     /*
      *@param URL 資源url  
      *@param timeoutInterval 超時時長
      */
    NSURLRequest *imgRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:MP3URL] cachePolicy:5 timeoutInterval:60.f];
    
     //創建下載任務  
    self.downTask = [self.downLoadSession downloadTaskWithRequest:imgRequest];
    
     //啟動下載任務  
    [self.downTask resume];
  • 實現代理方法
  #pragma mark 下載過程

  -(void)URLSession:(NSURLSession *)sessiondownloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
   //獲取下載進度
    double currentProgress = totalBytesWritten / (double)totalBytesExpectedToWrite;
    
    dispatch_async(dispatch_get_main_queue(), ^{
       
   //進行UI操作  設置進度條
        
        self.downLoadProgress.progress = currentProgress;
    
    });
    
  #pragma mark 下載完成 無論成功失敗

 -(void)URLSession:(NSURLSession *)session task: (NSURLSessionTask *)task didCompleteWithError:(NSError *)error
 {
    
        NSLog(@" function == %s, line == %d, error ==  %@",__FUNCTION__,__LINE__,error);
    
 }
   #pragma mark - 下載成功 獲取下載內容
 -(void)URLSession:(NSURLSession *)session   downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
 {
    //存儲本地
    
    //1.獲取Documents文件夾路徑 (不要將視頻、音頻等較大資源存儲在Caches路徑下)
        *方法一
        NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) lastObject];
        
        *方法二
        NSFileManager *manager = [NSFileManager defaultManager];
        NSURL * documentsDirectory = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0];
        
   //2.創建資源存儲路徑
       NSString *appendPath = [NSString stringWithFormat:@"/new.mp4"];
       NSString *file = [documentsPath stringByAppendingString:appendPath];

   //3.將下載好的視頻資源存儲在路徑下
     
      //刪除之前相同路徑的文件
      BOOL remove  = [manager removeItemAtPath:file error:nil];
      
      //將視頻資源從原有路徑移動到自己指定的路徑
      BOOL success = [manager copyItemAtPath:location.path toPath:file error:nil];

        if (success) {
    
      //回到主線程進行本地視頻播放
        dispatch_async(dispatch_get_main_queue(), ^{
            
        //創建視頻播放的本地路徑
            
        *** 請使用此方法創建本地路徑
        NSURL *url = [[NSURL alloc]initFileURLWithPath:file];
           
        *** 此方法創建的路徑無法播放 不是一個完整的路徑
        //NSURL *url2 = [[NSURL alloc]initWithString:file];
            
        //系統的視頻播放器
        AVPlayerViewController *controller = [[AVPlayerViewController alloc]init];
        //播放器的播放類
        AVPlayer * player = [[AVPlayer alloc]initWithURL:url];
            
        controller.player = player;
        //自動開始播放
        [controller.player play];
        //推出視屏播放器
        [self presentViewController:controller animated:YES completion:nil];
                      
            
        });
    }

 }    
  • NSURLSessionDownloadTask支持取消下載,可以在下載過程中隨時取消繼續下載,同時也可以實現恢復下載。
    • 取消下載 cancelByProducingResumeData

      //用當前NSURLSessionDownloadTask對象去調用取消下載
      
      [self.downTask cancelByProducingResumeData:
       ^(NSData * _Nullable resumeData) {
       
       //全局變量 接收當前下載的資源
       self.data = resumeData;
       }
       //將當前下載任務置為空
       self.downTask = nil;
      
      
    • 恢復下載 downloadTaskWithResumeData

             
      //恢復下載 實際上是建立了一個新的下載任務 去繼續之前的下載
            
      self.downTask = [self.downLoadSession downloadTaskWithResumeData:self.data];
        
       //開啟任務     
      [self.downTask resume];
            
        }
      

自動緩存

上面講到的是自己去手動操控整個下載過程,那么,很多伙伴就會講這樣是不是太麻煩了。如果你了解了NSURLSession的緩存策略,那么,你就會發現,我們這么寫確實是太麻煩了,那么下面我們就來學習一下NSURsession的自動緩存。

在開始之前,先介紹一下NSURLRequestUseProtocolCachePolicy的幾種緩存策略:

  1. NSURLRequestUseProtocolCachePolicy = 0, 默認的緩存策略, 如果緩存不存在,直接從服務端獲取。如果緩存存在,
    會根據response中的Cache-Control字段判斷下一步操作,如: Cache-Control字段為must-revalidata, 則詢問服務端該數據是否有更新,無更新的話直接返回給用戶緩存數據,若已更新,則請求服務端.
  1. NSURLRequestReloadIgnoringLocalCacheData = 1, 忽略本地緩存數據,直接請求服務端.
  1. NSURLRequestIgnoringLocalAndRemoteCacheData = 4, 忽略本地緩存,代理服務器以及其他中介,直接請求源服務端.
  1. NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData
  1. NSURLRequestReturnCacheDataElseLoad = 2, 有緩存就使用,不管其有效性(即忽略Cache-Control字段), 無則請求服務端.
  1. NSURLRequestReturnCacheDataDontLoad = 3, 死活加載本地緩存. 沒有就失敗. (確定當前無網絡時使用).

7>NSURLRequestReloadRevalidatingCacheData = 5, 緩存數據必須得得到服務端確認有效才使用(貌似是NSURLRequestUseProtocolCachePolicy中的一種情況)

因此,我們可以根據自己的需求去設置不同的緩存策略,而默認的就是如果有緩存就通過緩存獲取數據,沒有緩存就去請求網絡數據。
這里,我們通過一個請求圖片的例子,來窺探一下神奇的自動緩存。

  • 代碼:
    //創建一個UIImageView+MyImageView.h的類目,
     //在.h添加一個方法
    - (void)loadIamgeWithURL:(NSString *)urlString
    //在.m去實現此方法  
    - (void)loadIamgeWithURL:(NSString *)urlString
    {
    
    //創建下載圖片的url
    NSURL *url = [NSURL URLWithString:urlString];
    
    //創建網絡請求配置類
    NSURLSessionConfiguration * configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    
    //創建網絡會話
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:nil delegateQueue:[NSOperationQueue new]];
    
    //創建請求并設置緩存策略以及超時時長
    NSURLRequest *imgRequest = [NSURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:30.f];
     //*也可通過configuration.requestCachePolicy 設置緩存策略
    
    //創建一個下載任務
    NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:imgRequest completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
       
      //下載完成后獲取數據 此時已經自動緩存到本地,下次會直接從本地緩存獲取,不再進行網絡請求
     NSData * data = [NSData dataWithContentsOfURL:location];
      
      //回到主線程  
    dispatch_async(dispatch_get_main_queue(), ^{
    
      //設置圖片      
     self.image = [UIImage imageWithData:data];
     });
        
        
    }];
    
    
    //啟動下載任務
    [task resume];
    
    }

通過這種緩存策略,我們就可以實現圖片下載并自動緩存,當我們需要再次使用此資源的時候,它就會自動去本地緩存查找是否有已經下載好的圖片資源,
如果有就會直接去本地的,從而不需要再去進行網絡請求。可以在下載完成后,將網絡斷開進行測試。

總結

本次主要是講解了NSURLSession的下載,以及自動緩存策略。它的功能非常強大,還有很多沒來得及細細研究,如果你也喜歡它??,那就抓緊時間去研究吧~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,362評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,013評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,346評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,421評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,146評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,534評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,585評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,767評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,318評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,074評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,258評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,828評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,486評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,916評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,156評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,993評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,234評論 2 375

推薦閱讀更多精彩內容