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;


   不想写了,你彻底能够参考上面的步骤来完成你的后台下载!

相关文章
相关标签/搜索