NSURLSession是iOS7中新的网络接口,它与咱们熟悉的NSURLConnection是并列的。在程序在前台时,NSURLSession与NSURLConnection可以互为替代工作。注意,如果用户强制将程序关闭,NSURLSession会断掉。
 
NSURLSession提供的功能:
1.通过URL将数据下载到内存
2.通过URL将数据下载到文件系统
3.将数据上传到指定URL
4.在后台完成上述功能
 
工作流程
如果我们需要利用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请求):
4.当不再需要连接调用Session的invalidateAndCancel直接关闭,或者调用finishTasksAndInvalidate等待当前Task结束后关闭。这时Delegate会收到URLSession:didBecomeInvalidWithError:这个事件。Delegate收到这个事件之后会被解引用。
 
5.如果是一个BackgroundSession,在Task执行的时候,用户切到后台,Session会和ApplicationDelegate做交互。当程序切到后台后,在BackgroundSession中的Task还会继续下载,这部分文档叙述比较少,现在分三个场景分析下Session和Application的关系:
 
1)当加入了多个Task,程序没有切换到后台。
这种情况Task会按照NSURLSessionConfiguration的设置正常下载,不会和ApplicationDelegate有交互。
 
2)当加入了多个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的时候调用一下,如下:
  1. @implementation APLAppDelegate
  2. - (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier
  3. completionHandler:(void (^)())completionHandler
  4. {
  5. BLog();
  6. /*
  7. Store the completion handler. The completion handler is invoked by the view controller's checkForAllDownloadsHavingCompleted method (if all the download tasks have been completed).
  8. */
  9. self.backgroundSessionCompletionHandler = completionHandler;
  10. }
  11. //……
  12. @end
  13. //Session的Delegate
  14. @implementation APLViewController
  15. - (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session
  16. {
  17. APLAppDelegate *appDelegate = (APLAppDelegate *)[[UIApplication sharedApplication] delegate];
  18. if (appDelegate.backgroundSessionCompletionHandler) {
  19. void (^completionHandler)() = appDelegate.backgroundSessionCompletionHandler;
  20. appDelegate.backgroundSessionCompletionHandler = nil;
  21. completionHandler();
  22. }
  23. NSLog(@"All tasks are finished");
  24. }
  25. @end
 
3)当加入了多个Task,程序切到后台,下载完成了几个Task,然后用户又切换到前台。(程序没有退出)
  
切到后台之后,Session的Delegate仍然收不到消息。在下载完成几个Task之后再切换到前台,系统会先汇报已经下载完成的Task的情况,然后继续下载没有下载完成的Task,后面的过程同第一种情况。
 
4)当加入了多个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(或者说没有考虑全我上述的后台情况),但是大家有兴趣可以关注一下他们后续的更新情况。

IOS - NSURLSession的更多相关文章

  1. ios NSURLSession(iOS7后,取代NSURLConnection)使用说明及后台工作流程分析

    NSURLSession是iOS7中新的网络接口,它与咱们熟悉的NSURLConnection是并列的.在程序在前台时,NSURLSession与NSURLConnection可以互为替代工作.注意, ...

  2. iOS - NSURLSession 网络请求

    前言 NS_CLASS_AVAILABLE(NSURLSESSION_AVAILABLE, 7_0) @interface NSURLSession : NSObject @available(iOS ...

  3. ios NSURLSession后台传输

    http://www.appcoda.com/background-transfer-service-ios7/ http://www.raywenderlich.com/51127/nsurlses ...

  4. ios NSURLSession使用说明及后台工作流程分析

    NSURLSession是iOS7中新的网络接口,它与咱们熟悉的NSURLConnection是并列的.在程序在前台时,NSURLSession与NSURLConnection可以互为替代工作.注意, ...

  5. ios NSURLSession completeHandler默认调用quque

    注意 , [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSU ...

  6. iOS NSURLSession 封装下载类

    周六日鼓捣NSURLSession,效率虽然低下,最后还是有了一点点眉目.昨天和汤老师一起测试,又对它加深了一点理解.趁热打铁,先总结一下. 封装的类,对外用的方法,我写的是类方法,所以,在类方法中, ...

  7. iOS NSURLSession 下载

    周五的时候,有个新的需求,要下载脚本,帮助玩家自动打怪,应该也是挂机的意思吧! 组长让我设计界面,让汤老师设计数据等.我觉得数据的挑战性更大一点,然后就接过来了. 自己还没有形成互联网思维,所以弄了一 ...

  8. iOS ---------NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)

    遇到此问题的解决办法: 使用<NSURLSessionDelegate>中的didReceiveChallenge方法,方法中的代码如下: - (void)URLSession:(NSUR ...

  9. iOS NSURLSession VS NSURLConnection

    NSURLSession VS NSURLConnection NSURLSession可以看做是NSURLConnection的进化版,其对NSURLConnection的改进点有: * 根据每个S ...

随机推荐

  1. NOIP2005 等价表达式

    题目描述 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的要求是判断选项中哪些代数 ...

  2. myeclipse的项目导入到eclipse下,com.sun.org.apache.commons.beanutils.BeanUtils不能导入

    com.sun.org.apache.commons.beanutils.BeanUtils这个包不能引入了怎么办自己下了个org.apache.commons的jar包了之后,改成import or ...

  3. Redis Windows下安装部署

    下载Redis 在Redis的官网下载页上有各种各样的版本,我这次是在windows上部署的,要去GitHub上下载.我下载的是2.8.12版的,相信大家百度一下就可以搜到,这就是我们需要的: 启动R ...

  4. windows和linux文件共享

    ###Samba安装     [root@samba ~]# yum install -y samba*     [root@samba ~]# rpm -qa | grep samba ###开启s ...

  5. BPMN流程图的绘制的注意要点

    1.分支网关的表达式,是在选择的线上设置. 2.在分支网关上,可以设置一个默认线的id. 3.并行网关,必须有开始,有结束.

  6. hiberante学习笔记

    1.配置文件(hibernate映射文件): 让hibernate知道该怎么样去load,store持久化对象: 1.1 数据库忌讳的字段名 1) User 2) index 2.数据库表中一对多,多 ...

  7. PYTHON 购物车程序

    product_list = [ ('iphone',50000), ('Mac Pro',9900), ('Bike',8000), ('Watch',160000), ('Coffee',600) ...

  8. PHP中九大缓存技术总结

    PHP缓存包括PHP编译缓存和PHP数据缓存两种.PHP是一种解释型语言,属于边编译边运行的那种.这种运行模式的优点是程序修改很方便,但是运行效率却很低下.PHP编译缓存针对这种情况做改进处理,使得P ...

  9. qt-5.6.0 移植之tslib 配置及编译

    tslib 是qt启动时的一个触屏校正检验程序. 它的配置以及编译比较简单. 第一步, 下载tslib源码包: http://download.csdn.net/detail/MKNDG/329156 ...

  10. Python中sorted()方法

    Python中sorted()方法的用法 1.先说一下iterable,中文意思是迭代器. Python的帮助文档中对iterable的解释是:iteralbe指的是能够一次返回它的一个成员的对象.i ...