Links

10.NSURLConnection-和-NSURLSession

AFNetworking2.0->3.0NSURLSession替换了NSURLConnection

一: 背景

iOS早期版本提供了了NSURLConnection来执行网络请求. 应用开发人员需要管理链接池,并处理应用后台/中断以及请求的恢复. 从iOS7开始,苹果发布了NSURLSession用来替代NSURLConnection

二: NSURLSession 优点

使用NSURLSession具有以下优点:
  • NSURLSession对预防如其中的相关请求而言是一个可配置的容器.
    • 例如:对服务器的所有请求都可以配置成始终包含访问令牌
  • 你可以得到后台联网的所有好处.这有助于提高电池寿命/支持UIKit的多任务/使用与过程传输相同的委托模型
  • 热和网络任务都可以暂停/停止/重启.此处与NSURLConnection不同,此处不需要是NSOperation的子类
  • 你可以使用NSURLSession来配置会话以便在每个会话的基础上使用专用存储(缓存/cookie jar等)
  • 当使用NSURLConnection时,如果遇到了身份验证问题,问题会在任何一个请求中返回,你无法明确知道那个请求遇到了这个问题.使用NSURLSession,委托会处理身份验证
  • NSURLConnection有一些基于Block的异步方法,但委托不能使用它们.当发起一个请求时,要么成功,要么失败,即使它需要身份验证.
  • 使用NSURLSession你可以混合使用.也就是说,可以使用基于Block的异步方法,还可以设置委托以处理身份验证

三: NSURLConnection vs NSURLSession

  • NSURLConnection
    • 一个Connection对象代表一个任务,每个任务绑定一个configuration,所有的configuration共享一个全局储存器(global storage)
  • NSURLSession
    • 一个Session绑定一个configuration,一个Session可以创建多个Task,每个Session都有一个自己的储存器(private storage)

四: NSURLSession API

NSURLSessionConfiguration

  • 缓存,cookies,证书存储
  • 电池使用,网络服务类型
  • 请求的数量
  • 资源/请求超时时间
  • TLS协议
  • HTTP代理,cookies,头部
  • 子类话的存储器
Configuration对象默认是可变类型,它们被使用的时候相当于被copy了一份不可变的,在session中不能对中绑定的Configuration进行修改
  • 类型:
    • defaultSessionConfiguration : 系统默认
    • ephemeralSessionConfiguration : 仅内存缓存, 不做磁盘缓存的配置
    • backgroundSessionConfiguration : 这里需要指定一个identifier, identifier用来后台重连session对象. (做后台上传/下载就是这个config)

NSURLSessionTask

  • task被用来取代connection.一个task代表一个任务(相当于NSURLConnection对象)
  • 提供任务的状态和进度属性
  • 提供任务的取消/挂起/恢复功能
  • 区分data和upload任务
  • 提供断点续传的实现
  • 分类:
    • NSURLSessionTask : Task的抽象基类
    • NSURLSessionDataTask : 以NSData的形式接收一个URLRequest的内容
    • NSURLSessionUploadTask : 上传NSData或者本地磁盘中的文件, 完成后以NSData的形式接收一个URLRequest的响应
    • NSURLSessionDownloadTask : 下载完成后返回临时文件在本地磁盘的URL路径
    • NSURLSessionStreamTask : 用于建立一个TCP/IP连接

NSURLSessionDelegate

  • 一个代理对象可以处理所有NSURLSession方法
    • Session/task/dataTask/DownloadTask
  • 强引用代理对象直到session无效(与平时代理对象weak引用不同),session就会把全部task都取消/完成
  • 代理方法有可能会阻塞加载
    • 记得调用completion handler这个block去让session继续工作, 否则会阻塞起来

四: Session分类

  • sharedSession: 全局session有局限性
  • 自定义session: 自定义session,我们用的一般是这个
  • 后台session: 也是一种自定义session,专门用来做后台上传下载任务
类型由Configuration来决定

五: 后台传输

只支持上传下载任务,data任务不支持 只支持HTTPS 根据系统资源,很可能会取消掉后台任务,所以最好还是在前台完成 后台任务最好支持断点续传,分段传输
  • 系统创建一个守护进程
  • 当你的app正在运行的时候, 正常调用代理方法传输数据给你
  • 当你的app退出了(回到桌面/crash), 守护进程会继续他的工作, 直到需要重新认证或者完成所有任务
  • re-launch你的app, 然后re-create你的后台session, 然后后台session会re-connect守护进程.
  • 守护进程此时就会把数据给你.
  • 可以通过不同的identifier创建多个后台session.

线程安全

URLSession 的API全部都是线程安全的. 你可以在任何线程上创建session和tasks, task会自动调度到合适的代理队列中运行 后台传输的代理方法URLSession​Did​Finish​Events​For​Background​URLSession:​可能会在其他线程中被调用. 在该方法中你应该回到主线程然后调用completion handler去触发AppDelegate中的application:​handle​Events​For​Background​URLSession:​completion​Handler:​方法.

参考