[iOS]网络之NSURLSession的数据传输

来源:互联网 发布:税务大开杀戒 知乎 编辑:程序博客网 时间:2024/06/06 01:11

如何通过NSURLSession发起HTTP请求,这就是接下来要做的事情。

  • NSURLSession 简介
  • NSURLSession 任务行为
  • 使用NSURLSession之NSURLSessionDataTask

NSURLSession 简介

NSURLSession 是iOS系统提供“通过HTTP下载内容”的API,该API提供了丰富的方法来支持身份验证,让应用能够在后台或者挂起的时候执行后台下载。

可以用它创建一系列的会话,每个会话都会协调一组相关的数据传输任务。它是高度异步的,没有提供同步的方法。它提供支持两种完成回调,一种是实现block,另一种就是实现委托。

它提供了状态和进度的属性,除了将这些信息传递给委托。它还支持取消、重新启动(恢复)和暂停任务,并提供恢复中断、取消或失败下载的功能。

NSURLSession 任务行为

会话中任务行为取决与三件事:会话类型、任务类型、以及创建任务时应用是否处于前台。

会话类型
会话类型指的是它提供什么样的方式支持会话任务,提供了三种会话类型,是由会话配置对象(NSURLSessionConfiguration)的类型而确定。

默认会话(defaultSessionConfiguration),使用持久的基于磁盘的缓存,并在用户的密钥链中存储凭据。

临时会话(ephemeralSessionConfiguration),它不会将任何数据存储到磁盘;所有的缓存、凭据等保存在RAM中,并与会话绑定。因此当应用程序使NSURLSession对象消失时,它们将自动被清除。

后台会话 (backgroundSessionConfigurationWithIdentifier:(NSString *)identifier)类似于默认会话,只是一个单独的进程处理所有的数据传输。

从上面的描述能够看出来三者的区别,默认和临时会话的区别就是信息存放问题,默认利用的是持久化存储技术;而临时会话只是在RAM短暂的停留,如果创建的NSURLSession被回收了,相应的信息也会被清除;后台会话和默认的行为差不多,它两的区别就是,它能够在后台执行。

任务类型
任务类型指的是,要完成什么的任务,NSURLSession支持三种任务类型:数据任务、下载任务和上传任务

数据任务(NSURLSessionDataTask), 数据任务使用NSData对象发送和接收数据。数据任务的用于简短的、经常交互的请求。数据任务可以将数据完整的提供给完成回调。

下载任务(NSURLSessionDownloadTask), 以文件的形式检索数据,并在应用程序不运行时支持后台下载。

上传任务(NSURLSessionUploadTask), 以文件的形式发送数据,并在应用不运行时支持后台上传。

我们能够看到,数据任务主要担负数据量不是太大的请求,比如提交个人信息、查询个人信息等;上传任务和下载任务主要担负数据量非常大的请求,比如上传音乐、图片、视频、文件等;

NSURLSession前后台执行、会话的三种类型、任务的三种类型,你可以在前台用默认会话类型执行数据传输任务;前台用临时会话执行文件下载任务;也可以在后台用后台会话执行文件下载任务。

使用NSURLSession之NSURLSessionDataTask

简单的写一个例子,这个例子是默认会话类型、数据传输任务。

/** * 通过默认会话配置,创建默认NSURLSession对象。 * 1. [NSURLSessionConfiguration defaultSessionConfiguration] 默认配置对象 * 2. [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; 通过默认配置对象,创建默认会话类型对象 */ NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];/** * 默认会话类型执行数据传输任务 * 1. - (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler; * @param (NSURL *)url 网络地址 * @param completionHandler 任务完成以后的回调地址,需要实现。 */    NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:@"http://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {        NSLog(@"Got response %@ with error %@.\n", response, error);        NSLog(@"DATA:\n%@\nEND DATA\n", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);    }];[dataTask resume];

你可能会想,这也太简单了吧!我如果想用POST方法,并且需要提交数据怎么办?有办法,因为任何涉及到HTTP的“请求/相应”模型的框架,该框架都会提供两个类:请求(iOS提供的是NSRequest)和响应(NSResponse)这两个对象来封装。

        NSURLSessionConfiguration *defaultConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; //创建默认会话配置对象    /**     * 创建NSURLSession由两种API     * 1.  (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;     *  1.1 这种方式只需要给出配置对象就行,它适合数据传输任务且以Block的形式,作为回调方法     * 2. + (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;     *  2.1 这种方式,需要给出配置对象、代理对象、以及操作队列,这种方式适合上传、下载任务。     */    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];    NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration:defaultConfiguration delegate:delegate delegateQueue:[NSOperationQueue mainQueue]]; //创建默认会话对象    /**     * 我们发现HTTPBody只接收NSData类型,这个时候,我们就需要转换一下     */    NSError *error;    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:@{} options:NSJSONWritingPrettyPrinted error:&error];    /**     * 封装Request,提供POST方法去请求     */    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@""]];    [request setHTTPMethod:@"POST"]; //设置POST方法    [request setHTTPBody:jsonData];    /**     * 通过默认会话类型对象,发起数据传输任务,注意使用的API改变了。     */    NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {        NSLog(@"Got response %@ with error %@.\n", response, error);        NSLog(@"DATA:\n%@\nEND DATA\n", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);    }];    [postDataTask resume];//开始任务

其实NSURLSession使用起来还是很简单的,这里需要明白几个点:
1. 会话类型,会话类型是通过配置对象创建的
2. 任务类型,有数据传输、上传、下载;
3. 请求/响应模型,iOS提供的是NSURLRequest和NSResponse封装的。明白这一点,就能明白为什么session创建任务的时候,会有普通的NSURL和NSURLRequest这两种API;

这一篇讲述的是默认会话类型利用dataTaskWithRequest和dataTaskWithURL两种方式创建数据传输任务,为什么会有NSURL和NSURLRequest之分呢?是因为,调用者可能用get、post等方式发出请求,这种定制请求的需求,就需要通过NSURLRequest以及子类NSMutableURLRequest来实现了。NSURL只需要给出url地址,它会使用默认的方式来请求。

参考资料

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

原创粉丝点击