NSURLSession使用说明及后台工作流程分析
NSURLSession简介
NSURLSession是iOS7中新的网络接口,它与咱们熟悉的NSURLConnection是并列的。在程序在前台时,NSURLSession与NSURLConnection可以互为替代工作。注意,如果用户强制将程序关闭,NSURLSession会断掉。
NSURLSession提供的功能:
- 通过URL将数据下载到内存
- 通过URL将数据下载到文件系统
- 将数据上传到指定URL
- 在后台完成上述功能
工作流程
如果我们需要利用NSURLSession进行数据传输我们需要:
- 创建一个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使用说明及后台工作流程分析相关推荐
- 百度新闻后台逻辑流程分析
/*版权声明:可以任意转载,转载时请务必标明文章原始出处和作者信息 .*/ 百度新闻后台逻辑流程分析 CopyMiddle:张俊林 TimeStamp:2008年1月9日 今天分析了一下百度新闻,琢磨 ...
- 16.U-boot的工作流程分析-2440
16.U-boot的工作流程分析-2440 分析的流程: 程序入口 第一阶段程序分析 第二阶段程序分析 2440开发板: 1.uboot的入口: 要看uboot工程的入口,首先打开顶层目录的Makef ...
- K8S架构设计及工作流程分析
Kubernetes架构设计 核心组件 api server 功能 controller manager 负责维护集群的状态 scheduler 负责资源的调度按照预定的调度策略将Pod调度到相应的机 ...
- kafka的基本概念和工作流程分析
为什么需要消息队列 周末无聊刷着手机,某宝网APP突然蹦出来一条消息"为了回馈老客户,女朋友买一送一,活动仅限今天!".买一送一还有这种好事,那我可不能错过!忍不住立马点了去.于是 ...
- 【转载】csr8670--sink工程的大致工作流程分析(以speaker为例)二
csr8670--sink工程的大致工作流程分析(以speaker为例)二 1.编解码任务的初始化 继续接着流程一分析: 1.1 当连接初始化完成之后,如下所示会调用编解码的初始化任务:这个编解码的任 ...
- 【SemiDrive源码分析】【X9芯片启动流程】14 - freertos_safetyos目录Cortex-R5 SafetyOS/RTOS工作流程分析
[SemiDrive源码分析][X9芯片启动流程]14 - freertos_safetyos目录Cortex-R5 SafetyOS/RTOS工作流程分析 一.SafetyOS 工作流程分析 1. ...
- 你想要的系列:网络请求框架OkHttp3全解系列 - (二)OkHttp的工作流程分析
Okhttp系列文章: 你想要的系列:网络请求框架OkHttp3全解系列 - (一)OkHttp的基本使用 你想要的系列:网络请求框架OkHttp3全解系列 - (二)OkHttp的工作流程分析 你想 ...
- Android 7.0 WifiMonitor工作流程分析
2019独角兽企业重金招聘Python工程师标准>>> 在wifi启动扫描的分析过程中,出现了多次WifiMonitor的操作,在此分析一下这个函数是如何工作的. 在Android的 ...
- android的构成和工作流程,分析Android中View的工作流程
8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 在分析View的工作流程时,需要先分析一个很重要的类,MeasureSpec.这个类在View的测量(Measure)过 ...
最新文章
- 用C#编写ActiveX控件(三) 转载
- Java中栈、堆和常量池
- 互联网分布式架构技术概述
- html网页加密最终版,【原】记一次加密网页html的研究
- 【转贴备忘】[教程]iPhone 實機開發 Part 1 - HelloWorld
- mysqld进程 ut_delay 占用率过高
- 编译运行linux0.12,linux0.12 编译过程
- div不继承父类样式_Java三大特性之继承
- Introduction to Oracle9i: SQL------- left join 和 left outer join 的区别
- 有趣的算法(五):一文读懂二叉搜索树的插入、删除
- jQuery基础--选择器
- c51步进电机程序汇编语言,51单片机驱动步进电机(汇编语言)
- 如何制作刷爆朋友圈的H5
- Laravel执行seeder命令出现class *** does not exist
- 径向渐变加阴影html,CSS径向渐变阴影 - 反转
- 即使挨骂也要说:刚毕业,就别去初创企业了
- 【哈佛大学:计算生物学 生物信息学】学习记录(二)
- 全网页CSS 超链接无下划线
- 3年Java后端开发面试题总结
- 行业认证标准:如何达到DISA ASD STIG规范进行软件开发
热门文章
- 利用日志审计追踪APT***
- .NET 数据访问中间件 HyperDAL v1.1 FAQ
- 【异步编程】Part3:取消异步操作
- burpsuite配置指南
- TFTP commons-net-3.3.jar
- HDU 2181 哈密顿绕行世界问题【DFS】
- 《包青天》中的《鸳鸯蝴蝶梦》单元,剧中有一个很漂亮的女子叫“离垢”
- 算法----返回Excel相应的列序号
- RxJava 常用总结以及原理理解
- BottomNavigationView+ViewPager+Fragment仿微信底部导航栏