NSURLSession简介

NSURLSession是iOS7中新的网络接口,它与咱们熟悉的NSURLConnection是并列的。在程序在前台时,NSURLSession与NSURLConnection可以互为替代工作。注意,如果用户强制将程序关闭,NSURLSession会断掉。

NSURLSession提供的功能:

  • 通过URL将数据下载到内存
  • 通过URL将数据下载到文件系统
  • 将数据上传到指定URL
  • 在后台完成上述功能

工作流程

如果我们需要利用NSURLSession进行数据传输我们需要:

  1. 创建一个NSURLSessionConfiguration,用于第二步创建NSSession时设置工作模式和网络设置:

工作模式分为:

  • 一般模式(default):工作模式类似于原来的NSURLConnection,可以使用缓存的Cache,Cookie,鉴权。
  • 及时模式(ephemeral):不使用缓存的Cache,Cookie,鉴权。
  • 后台模式(background):在后台完成上传下载,创建Configuration对象的时候需要给一个NSString的ID用于追踪完成工作的Session是哪一个(后面会讲到)。

网络设置:参考NSURLConnection中的设置项。

  1. 创建一个NSURLSession,系统提供了两个创建方法:

  • sessionWithConfiguration:
  • sessionWithConfiguration:delegate:delegateQueue:

    第一个粒度较低就是根据刚才创建的Configuration创建一个Session,系统默认创建一个新的OperationQueue处理Session的消息。

    第二个粒度比较高,可以设定回调的delegate(注意这个回调delegate会被强引用),并且可以设定delegate在哪个OperationQueue回调,如果我们将其设置为[NSOperationQueue mainQueue]就能在主线程进行回调非常的方便。

  2.创建一个NSURLRequest调用刚才的NSURLSession对象提供的Task函数,创建一个NSURLSessionTask。

  根据职能不同Task有三种子类:

  • NSURLSessionUploadTask:上传用的Task,传完以后不会再下载返回结果;
  • NSURLSessionDownloadTask:下载用的Task;
  • NSURLSessionDataTask:可以上传内容,上传完成后再进行下载。

  得到的Task,调用resume开始工作。

  3. 如果是细粒度的Session调用,Session与Delegate会在指定的OperationQueue中进行交互,以咱们下载例子,交互过程的顺序图如下(假如不需要鉴权,即非HTTPS请求):

  5. 当不再需要连接调用Session的invalidateAndCancel直接关闭,或者调用finishTasksAndInvalidate等待当前Task结束后关闭。这时Delegate会收到URLSession:didBecomeInvalidWithError:这个事件。Delegate收到这个事件之后会被解引用。

  6. 如果是一个BackgroundSession,在Task执行的时候,用户切到后台,Session会和ApplicationDelegate做交互。当程序切到后台后,在BackgroundSession中的Task还会继续下载,这部分文档叙述比较少,现在分三个场景分析下Session和Application的关系:

  • 当加入了多个Task,程序没有切换到后台。

  这种情况Task会按照NSURLSessionConfiguration的设置正常下载,不会和ApplicationDelegate有交互。

  • 当加入了多个Task,程序切到后台,所有Task都完成下载。

  在切到后台之后,Session的Delegate不会再收到,Task相关的消息,直到所有Task全都完成后,系统会调用ApplicationDelegate的application:handleEventsForBackgroundURLSession:completionHandler:回调,之后“汇报”下载工作,对于每一个后台下载的Task调用Session的Delegate中的URLSession:downloadTask:didFinishDownloadingToURL:(成功的话)和URLSession:task:didCompleteWithError:(成功或者失败都会调用)。

  之后调用Session的Delegate回调URLSessionDidFinishEventsForBackgroundURLSession:。

  注意:在ApplicationDelegate被唤醒后,会有个参数ComplietionHandler,这个参数是个Block,这个参数要在后面Session的Delegate中didFinish的时候调用一下,如下:

@implementation APLAppDelegate

- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier

completionHandler:(void (^)())completionHandler

{

BLog();

/*

Store the completion handler. The completion handler is invoked by the view controller's checkForAllDownloadsHavingCompleted method (if all the download tasks have been completed).

*/

self.backgroundSessionCompletionHandler = completionHandler;

}

//……

@end

//Session的Delegate

@implementation APLViewController

- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session

{

APLAppDelegate *appDelegate = (APLAppDelegate *)[[UIApplication sharedApplication] delegate];

if (appDelegate.backgroundSessionCompletionHandler) {

void (^completionHandler)() = appDelegate.backgroundSessionCompletionHandler;

appDelegate.backgroundSessionCompletionHandler = nil;

completionHandler();

}

NSLog(@"All tasks are finished");

}

@end

  • 当加入了多个Task,程序切到后台,下载完成了几个Task,然后用户又切换到前台。(程序没有退出)

  切到后台之后,Session的Delegate仍然收不到消息。在下载完成几个Task之后再切换到前台,系统会先汇报已经下载完成的Task的情况,然后继续下载没有下载完成的Task,后面的过程同第一种情况。

  • 当加入了多个Task,程序切到后台,几个Task已经完成,但还有Task还没有下载完的时候关掉强制退出程序,然后再进入程序的时候。(程序退出了)

  最后这个情况比较有意思,由于程序已经退出了,后面没有下完Session就不在了后面的Task肯定是失败了。但是已经下载成功的那些Task,新启动的程序也没有听“汇报”的机会了。经过实验发现,这个时候之前在NSURLSessionConfiguration设置的NSString类型的ID起作用了,当ID相同的时候,一旦生成Session对象并设置Delegate,马上可以收到上一次关闭程序之前没有汇报工作的Task的结束情况(成功或者失败)。但是当ID不相同,这些情况就收不到了,因此为了不让自己的消息被别的应用程序收到,或者收到别的应用程序的消息,起见ID还是和程序的Bundle名称绑定上比较好,至少保证唯一性。

总结

  就像前面说的,在普通的应用场景下NSURLSession与NSURLConnection相比没有什么优势,但是在程序切换到后台之后Background的Session就显得更加灵活了。

  另外,现在主流的网络开发框架AFNetworking已经更新到了2.0(只支持iOS 6 / iOS 7),其中最重要的一个更新就是添加了NSURLSession相关的支持。虽然就我现在(2013.10.13)看到他们的源码中,还没有完全的支持后台的Session(或者说没有考虑全我上述的后台情况),但是大家有兴趣可以关注一下他们后续的更新情况。

参考资料:

苹果官方文档:

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/URLLoadingSystem/Articles/UsingNSURLSession.html#//apple_ref/doc/uid/TP40013509-SW1

注意:苹果又开始不更新Xcode 中的文档,然后悄悄在网上更新了,大家请关注相关文档最后的更新时间,以最新的为准

AFNetworking 2.0:

https://github.com/AFNetworking/AFNetworking/

转载于:https://www.cnblogs.com/biosli/p/iOS_Network_URL_Session.html

NSURLSession使用说明及后台工作流程分析相关推荐

  1. 百度新闻后台逻辑流程分析

    /*版权声明:可以任意转载,转载时请务必标明文章原始出处和作者信息 .*/ 百度新闻后台逻辑流程分析 CopyMiddle:张俊林 TimeStamp:2008年1月9日 今天分析了一下百度新闻,琢磨 ...

  2. 16.U-boot的工作流程分析-2440

    16.U-boot的工作流程分析-2440 分析的流程: 程序入口 第一阶段程序分析 第二阶段程序分析 2440开发板: 1.uboot的入口: 要看uboot工程的入口,首先打开顶层目录的Makef ...

  3. K8S架构设计及工作流程分析

    Kubernetes架构设计 核心组件 api server 功能 controller manager 负责维护集群的状态 scheduler 负责资源的调度按照预定的调度策略将Pod调度到相应的机 ...

  4. kafka的基本概念和工作流程分析

    为什么需要消息队列 周末无聊刷着手机,某宝网APP突然蹦出来一条消息"为了回馈老客户,女朋友买一送一,活动仅限今天!".买一送一还有这种好事,那我可不能错过!忍不住立马点了去.于是 ...

  5. 【转载】csr8670--sink工程的大致工作流程分析(以speaker为例)二

    csr8670--sink工程的大致工作流程分析(以speaker为例)二 1.编解码任务的初始化 继续接着流程一分析: 1.1 当连接初始化完成之后,如下所示会调用编解码的初始化任务:这个编解码的任 ...

  6. 【SemiDrive源码分析】【X9芯片启动流程】14 - freertos_safetyos目录Cortex-R5 SafetyOS/RTOS工作流程分析

    [SemiDrive源码分析][X9芯片启动流程]14 - freertos_safetyos目录Cortex-R5 SafetyOS/RTOS工作流程分析 一.SafetyOS 工作流程分析 1. ...

  7. 你想要的系列:网络请求框架OkHttp3全解系列 - (二)OkHttp的工作流程分析

    Okhttp系列文章: 你想要的系列:网络请求框架OkHttp3全解系列 - (一)OkHttp的基本使用 你想要的系列:网络请求框架OkHttp3全解系列 - (二)OkHttp的工作流程分析 你想 ...

  8. Android 7.0 WifiMonitor工作流程分析

    2019独角兽企业重金招聘Python工程师标准>>> 在wifi启动扫描的分析过程中,出现了多次WifiMonitor的操作,在此分析一下这个函数是如何工作的. 在Android的 ...

  9. android的构成和工作流程,分析Android中View的工作流程

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 在分析View的工作流程时,需要先分析一个很重要的类,MeasureSpec.这个类在View的测量(Measure)过 ...

最新文章

  1. 用C#编写ActiveX控件(三) 转载
  2. Java中栈、堆和常量池
  3. 互联网分布式架构技术概述
  4. html网页加密最终版,【原】记一次加密网页html的研究
  5. 【转贴备忘】[教程]iPhone 實機開發 Part 1 - HelloWorld
  6. mysqld进程 ut_delay 占用率过高
  7. 编译运行linux0.12,linux0.12 编译过程
  8. div不继承父类样式_Java三大特性之继承
  9. Introduction to Oracle9i: SQL------- left join 和 left outer join 的区别
  10. 有趣的算法(五):一文读懂二叉搜索树的插入、删除
  11. jQuery基础--选择器
  12. c51步进电机程序汇编语言,51单片机驱动步进电机(汇编语言)
  13. 如何制作刷爆朋友圈的H5
  14. Laravel执行seeder命令出现class *** does not exist
  15. 径向渐变加阴影html,CSS径向渐变阴影 - 反转
  16. 即使挨骂也要说:刚毕业,就别去初创企业了
  17. 【哈佛大学:计算生物学 生物信息学】学习记录(二)
  18. 全网页CSS 超链接无下划线
  19. 3年Java后端开发面试题总结
  20. 行业认证标准:如何达到DISA ASD STIG规范进行软件开发

热门文章

  1. 利用日志审计追踪APT***
  2. .NET 数据访问中间件 HyperDAL v1.1 FAQ
  3. 【异步编程】Part3:取消异步操作
  4. burpsuite配置指南
  5. TFTP commons-net-3.3.jar
  6. HDU 2181 哈密顿绕行世界问题【DFS】
  7. 《包青天》中的《鸳鸯蝴蝶梦》单元,剧中有一个很漂亮的女子叫“离垢”
  8. 算法----返回Excel相应的列序号
  9. RxJava 常用总结以及原理理解
  10. BottomNavigationView+ViewPager+Fragment仿微信底部导航栏