热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

iOS7NSURLSession

为什么80%的码农都做不了架构师?在iOS7之前使用的网络服务是通过使用NSURLConnection中的全局状态来管理Cookie和身份验证,因

为什么80%的码农都做不了架构师?>>>   hot3.png

   在iOS 7之前使用的网络服务是通过使用NSURLConnection中的全局状态来管理COOKIE和身份验证,因此可能导致两个不同的链接同时使用这个设置时产生冲突。在iOS7的NSURLSession 中苹果公司决定改掉这个被人诟病的毛病。

    在这里我们将使用NSURLSession来王成三种不同的下载方案。下面的文章我们将实现:


  Simple dowload

     如果我们要利用NSURLSession进行数据传输我们需要做如下的步骤

   1.创建一个NSURLSessionConfiguration

   2.创建NSSession并通过第一步创建好的NSURLSessionConfiguration来设置工作模式和网络设置

   工作模式分为:

  默认模式(default):工作模式类似鱼原来的NSURLConnection,可以使用缓存的Cache,COOKIE 等

  实时模式(ephemeral):不是用缓存的Cache,COOKIE和授权

  后台模式 (background):在后台完成上传和下载,创建Configuration对象的时候需要给NSString一个ID用于追踪完成工作的Session是那一个。


  对于简单的下载我们将只使用默认的会话:

    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;


   不想写了,你完全可以参考上面的步骤来完成你的后台下载!


转载于:https://my.oschina.net/zboy/blog/203799


推荐阅读
  • ### 优化后的摘要本学习指南旨在帮助读者全面掌握 Bootstrap 前端框架的核心知识点与实战技巧。内容涵盖基础入门、核心功能和高级应用。第一章通过一个简单的“Hello World”示例,介绍 Bootstrap 的基本用法和快速上手方法。第二章深入探讨 Bootstrap 与 JSP 集成的细节,揭示两者结合的优势和应用场景。第三章则进一步讲解 Bootstrap 的高级特性,如响应式设计和组件定制,为开发者提供全方位的技术支持。 ... [详细]
  • 本文总结了一些开发中常见的问题及其解决方案,包括特性过滤器的使用、NuGet程序集版本冲突、线程存储、溢出检查、ThreadPool的最大线程数设置、Redis使用中的问题以及Task.Result和Task.GetAwaiter().GetResult()的区别。 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 秒建一个后台管理系统?用这5个开源免费的Java项目就够了
    秒建一个后台管理系统?用这5个开源免费的Java项目就够了 ... [详细]
  • 近期,微信公众平台上的HTML5游戏引起了广泛讨论,预示着HTML5游戏将迎来新的发展机遇。磊友科技的赵霏,作为一名HTML5技术的倡导者,分享了他在微信平台上开发HTML5游戏的经验和见解。 ... [详细]
  • IOS Run loop详解
    为什么80%的码农都做不了架构师?转自http:blog.csdn.netztp800201articledetails9240913感谢作者分享Objecti ... [详细]
  • Java高并发与多线程(二):线程的实现方式详解
    本文将深入探讨Java中线程的三种主要实现方式,包括继承Thread类、实现Runnable接口和实现Callable接口,并分析它们之间的异同及其应用场景。 ... [详细]
  • 本地存储组件实现对IE低版本浏览器的兼容性支持 ... [详细]
  • 本文详细介绍了在CentOS 6.5 64位系统上使用阿里云ECS服务器搭建LAMP环境的具体步骤。首先,通过PuTTY工具实现远程连接至服务器。接着,检查当前系统的磁盘空间使用情况,确保有足够的空间进行后续操作,可使用 `df` 命令进行查看。此外,文章还涵盖了安装和配置Apache、MySQL和PHP的相关步骤,以及常见问题的解决方法,帮助用户顺利完成LAMP环境的搭建。 ... [详细]
  • 大家好,我是李白。本文将分享一个从零开始的全栈项目,涵盖了设计、前端、后端和服务端的全面学习过程。通过这个项目,我希望能够帮助初学者更好地理解和掌握全栈开发的技术栈。 ... [详细]
  • 本文介绍如何使用 Python 的 DOM 和 SAX 方法解析 XML 文件,并通过示例展示了如何动态创建数据库表和处理大量数据的实时插入。 ... [详细]
  • 本文详细介绍了 InfluxDB、collectd 和 Grafana 的安装与配置流程。首先,按照启动顺序依次安装并配置 InfluxDB、collectd 和 Grafana。InfluxDB 作为时序数据库,用于存储时间序列数据;collectd 负责数据的采集与传输;Grafana 则用于数据的可视化展示。文中提供了 collectd 的官方文档链接,便于用户参考和进一步了解其配置选项。通过本指南,读者可以轻松搭建一个高效的数据监控系统。 ... [详细]
  • 您的数据库配置是否安全?DBSAT工具助您一臂之力!
    本文探讨了Oracle提供的免费工具DBSAT,该工具能够有效协助用户检测和优化数据库配置的安全性。通过全面的分析和报告,DBSAT帮助用户识别潜在的安全漏洞,并提供针对性的改进建议,确保数据库系统的稳定性和安全性。 ... [详细]
  • 本文深入解析了Linux系统中常用的文件和目录操作命令,包括但不限于`ls`、`cd`等。通过详细讲解每个命令的功能、语法及应用场景,帮助读者掌握这些基本工具的使用方法,提升在Linux环境下的操作效率。此外,文章还介绍了如何结合选项和参数来实现更复杂的文件管理任务,为初学者提供了丰富的实践示例和技巧。 ... [详细]
  • 体积小巧的vsftpd与pureftpd Docker镜像在Unraid系统中的详细配置指南:支持TLS加密及IPv6协议
    本文详细介绍了如何在Unraid系统中配置体积小巧的vsftpd和Pure-FTPd Docker镜像,以支持TLS加密和IPv6协议。通过这些配置,用户可以实现安全、高效的文件传输服务,适用于各种网络环境。配置过程包括镜像的选择、环境变量的设置以及必要的安全措施,确保了系统的稳定性和数据的安全性。 ... [详细]
author-avatar
王海937_264
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有