iOS7 - NSURLSession

   在iOS 7以前使用的網絡服務是經過使用NSURLConnection中的全局狀態來管理Cookie和身份驗證,所以可能致使兩個不一樣的連接同時使用這個設置時產生衝突。在iOS7的NSURLSession 中蘋果公司決定改掉這個被人詬病的毛病。緩存

    在這裏咱們將使用NSURLSession來王成三種不一樣的下載方案。下面的文章咱們將實現:安全


  Simple dowload
服務器

     若是咱們要利用NSURLSession進行數據傳輸咱們須要作以下的步驟
cookie

   1.建立一個NSURLSessionConfiguration網絡

   2.建立NSSession並經過第一步建立好的NSURLSessionConfiguration來設置工做模式和網絡設置session

   工做模式分爲:app

  默認模式(default):工做模式相似魚原來的NSURLConnection,可使用緩存的Cache,cookie 等異步

  實時模式(ephemeral):不是用緩存的Cache,Cookie和受權async

  後臺模式 (background):在後臺完成上傳和下載,建立Configuration對象的時候須要給NSString一個ID用於追蹤完成工做的Session是那一個。url


  對於簡單的下載咱們將只使用默認的會話:

    NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];

     一旦一個配置對象被建立那麼它的屬性就能夠控制它的動做。例如,它能夠設置接收TLS安全級別,無論cookies是否容許和是否超時。這裏兩個比較有趣的特性是allowsCellularAccess和discretionary。前者指定的設備是否被容許運行的網絡session,只有一個蜂窩數據可用。設置一個會話做爲全權使操做系統來安排網絡訪問明智的時間 - 也就是當一個無線網絡可用,而當該設備具備良好的動力性。這主要是利用background session,所以默認爲true的background session。

   一旦咱們有一個會話配置對象,咱們能夠建立會話自己。

NSURLSession *inProcessSession;

inProcessSession = [NSURLSession sessionWithConfiguration:sessionConfig   delegate:self  delegateQueue:nil];

             注意這裏咱們也設置本身做爲本身的一個委託。委託方法用來通知咱們的數據傳輸的進度和當挑戰驗證請求信息 咱們將很快實施一些適當的方法。

          數據傳輸封裝在任務 - 其中有三種類型:

            NSURLSessionUploadTask:上傳用的Task,傳完以後不會再下載返回結果;

            NSURLSessionDownloadTask:下載用的Task;

            NSURLSessionDataTask:能夠上傳內容,上傳完成以後再進行下載。

  爲了在會話中進行傳輸,咱們須要建立一個任務。對於一個簡單的文件下載:

        NSString *url = @"hettp://appropriate/url/here";

        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];

        NSURLSessionDownloadTask *cancellabelTask = [inProcessSession downloadTaskWithRequest:request];

       [cancellableTask resume];


     這一切就這麼簡單 - 如今會話將異步嘗試下載該文件在指定的URL。

       爲了弄個所需的文件下載,咱們須要實現一個委託方法:


         - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location

{

       //咱們已經成功的完成下載,如今要保存文件

      NSFileManage *fileManager = [NSFileManager defauleManager];

      NSArray *URLs = [fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDoma\inMask];

      NSURL *dcoumentsDirectory = URLs[0];

      NSURL *destinationPath = [documentsDirectory URLByAppendingPathCOmponent:[location lastPathComponent]];

       NSError *error;


     //確保咱們已經覆蓋了已經存在的

         [fileManager removeItemAtURL:destinationPath error:NULL];

         BOOL success = [fileManager copyItemAtURL:location  toURL:destinationPath error:&error];


       if (success)

{

    dispatch_async(dispatch_get_main_queue(), ^{

         UIImage *image = [UIImage imageWithContentOfFile:[destinationPath path]];

         self.imageView.image = image;

         self.imageView.contentMode = UIViewContentModeScaleAspectFill;

          self.imageView.hidden = NO;

});

}  else

{

    NSLog(@"Couldn't copy the dowloaded file");

}


      if (downloadTask == cancelableTask){

           cancellableTask = nil;


       }

}

     這種方法是在NSURLSessionDownloadTaskDelegate定義。咱們得到經過下載的文件的臨時位置,因此在這段代碼中咱們保存它關閉的文件目錄,而後(由於咱們有一個圖片)顯示給用戶。

     上述委託方法只被調用,若是下載任務成功完成。下面的方法是NSURLSessionDelegate和被調用每個任務完成後,不論它是否成功完成。

 - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task dedCompleteWithError:(NSError *)error

     {

       dispatch_async(dispatch_get_mian_queue(),^{self.progressInicator.hiddent = YES;})

}


若是錯誤對象爲零則任務完成沒有問題。不然,有可能對其進行查詢,找出問題是什麼。若是部分下載已完成,則錯誤對象包含對一個NSData對象,它能夠用來恢復傳輸在稍後的階段。


跟蹤進度

你會注意到,咱們在最後一節的末尾藏進度指示任務完成方法的一部分。此更新進度條的進度再簡單不過了。還有就是這是在任務的生命週期被稱爲零次或屢次額外的委託方法:


  - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int62_t)bytesWritten BytesWritten:(int64_t)totalBytesWritten totalByteExpectedToWrite:(int64_t)totalBytesExpectedToWrite

{

    double currentProgress = totalBytesWritten/(double)totalBytesExpectedToWrite;

     dispatch_async(dispatch_get_main_queue() ^{self.progressIndicator.hidden = NO;  self.progressIndicator.progress = currentProgress;})

}

這是另外一種方法,它是NSURLSessionDownloadTaskDelegate的一部分,咱們在這裏使用它來
估計進度和更新進度指示器。


退出下載

  即便NSURLConnection被取消也不會消失。這是一個簡單的能力,與取消NSURLSessionTask不一樣。

   -(IBAction)cancelCancellabel:(id)sender{

      if (cancellableTask){

      [cancellabelTask cancel];

      cancellableTask = nil;

     }

}


 就是這麼簡單!值得一提的是UIRLSession:task:didCompleteWithError:delegate方法將被在調用一次後取消,通常你可以適當的更新UI。這極可能取消任務URLSession:downloadTask:didWriteData:BytesWritten:totalBytesExpectedToWrite:方法,可能會被調用,可是didComplete方法可定時最後的。


    斷點續傳下載

 它也能夠很容易地恢復下載。還存在另外一種取消方法,該方法提供了一個NSData對象能夠用來建立一個新的任務繼續傳輸在稍後的階段。若是服務器支持續傳而後將數據對象將包括已經下載的內容。


- (IBAction)cancelCancellabel:(id)sender{

   if(self.resumableTask){

     [self.resumableTask cancelByProducingResumeData:^(NSData *resumeData) { partialDownload = resumeData;   self.resumableTask = nil;}];

      }

}

       在這裏,咱們已經把恢復數據到ivar,咱們之後能夠用它來恢復下載。
在建立下載任務,而不是提供你能提供一個恢復數據對象的請求:

if (!self.resumableTask){

     if(partialDownload){

        self.resumableTask = [inProcessSession  downloadTaskWithResumeData:partialDownload];

      }else{

            NSString *url = @"dizhi";

             NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];

             self.resumableTask = [inProcessSession downloadTaskWithResques:request];

    }

    [self.resumableTask resume];

}

若是咱們已經有一個paritialDownload對象,而後建立一個task來使用這個對象,不然咱們將像之前同樣建立task。惟一一件須要記住的事情就是當process結束咱們須要設置 partialDownload = nil;


   不想寫了,你徹底能夠參考上面的步驟來完成你的後臺下載!

相關文章
相關標籤/搜索