
Snip20151216_3.png
NSURLSession使用注意事项
-
NSURLSession- 所谓
网络会话,就是一段同服务器之间的通讯。一个session可以由数个数据传输任务构成。 - session类型由
NSURLSessionConfiguration对象决定:-
Default Session / 默认会话- 功能类似于
NSURLConnection。 - 磁盘缓存。
- 用
keychain保存证书。
- 功能类似于
-
Ephemeral Session / 临时会话- 内存缓存。
- 不保存证书。
-
invalidate后,所有信息会被抹去。
-
Background Session / 后台会话- app退出后,
数据传输任务被移动至一个独立的进程中继续执行。 - 任务在后台执行时,遇到错误会
自动重试。 - 除了某些限制之外,其它同特性
默认会话相似。
- app退出后,
-
- 所谓
-
NSURLSessionTask- 会话期间所执行的
数据传输任务。 - task类型(所有的task都通过
NSURLSession创建)-
NSURLSessionDataTask / 数据任务- 以
NSData的形式接收服务器返回的数据。 -
分段监测数据。 - 适用于
频繁的短小通讯。
- 以
-
NSURLSessionDownloadTask / 下载任务- 以
文件的形式接收服务器返回的数据。 - 解决了大文件下载的
内存管理问题。 - 能够
断点续传:- 其
cancelByProducingResumeData:会生成一个XML数据,保存了续传所需的信息。 - 利用这个数据重新创建
download task,以继续下载。 - 只有通过
GET方法获取的文件才可以断点续传。
- 其
- 支持
后台下载。
- 以
-
NSURLSessionUploadTask / 上传任务- 向服务器发送
文件数据。 - 支持
后台上传。 - 一般不使用,原因如下:
-
不能自动封装请求体,即仍然需要手动创建Request body。 - 如果上传的是
NSData数据,可以使用POST方法;但对于磁盘文件,只能使用PUT方法,现在基本没有服务器支持这一方法。
-
- 向服务器发送
-
- 会话期间所执行的
-
后台任务- session必须通过
backgroundSessionConfigurationWithIdentifier:创建。 - 在一个
独立进程中执行。 - 必须使用
delegate实现回调。 - 只支持
HTTP/HTTPs协议。 - 自动接受
Redirection。 - 上传任务必须
从文件上传。 - 如果任务开始时
app处于后台,那么configuration对象的discretinary属性被设置为YES。
- session必须通过
/*
后台任务执行流程
*/
(app已退出)后台任务进行中--->
==================================
情况A:任务完成 / 需要验证证书--->
1. app代理方法application:handleEventsForBackgroundURLSession:completionHandler:被调用
2. 在其中所需执行的操作:
- 保存completionHandler
- 根据identifier创建一个background configuration
- 创建background session
--->
3. 后台任务被自动纳入新建session--->
4. 所有任务完成,session代理方法URLSessionDidFinishEventsForBackgroundURLSession:被调用--->
5. 执行之前保存的completionHandler(注意,其属于UIKit,必须在主线程上执行)
==================================
情况B:用户再次启动app--->
1. 在app代理方法application:didFinishLaunchingWithOptions:中根据identifier,创建仍有未完成任务的session对象(一个或多个)
--->
2. 后台任务被自动纳入新建session--->
- 示例代码
/*
Session代理方法
*/
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session
{
NSLog(@"所有后台任务已经完成");
if (session.configuration.identifier) {
// 执行实现保存的后台session回调
self.backgrondSessionCompletionHandler();
}
}
======================================
/*
app代理方法
*/
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler
{
// 创建配置对象
NSURLSessionConfiguration *config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:identifier];
// 根据配置对象创建session
NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self.sessionDelegate delegateQueue:[NSOperationQueue new]];
NSLog(@"session被重新创建");
// 保存completionHandler
self.backgrondSessionCompletionHandler = completionHandler;
}
-
SSL / TLS 验证-
Session-Level Challenges / 会话级别验证,首先尝试调用session代理方法URLSession:didReceiveChallenge:completionHandler:。其次尝试调用task打理方法URLSession:task:didReceiveChallenge:completionHandler:。 -
Non-Session-Level Challenges / 非会话级别验证,只调用task代理方法URLSession:task:didReceiveChallenge:completionHandler:。
-
-
注意事项- session的数据传输任务能且只能
在子线程上执行。 - 只有NSURLConnection才支持
同步任务。 - 同时实现
回调block和代理方法,默认只调用前者。 - 如果采用block进行回调,系统会对session进行默认
代理支持。 - session的
delegate负责处理session和task级别的回调。 - 用完的session
必须释放,否则会造成内存泄漏。因为session会对其delegate进行强引用。
- session的数据传输任务能且只能