iOS基础深入补完计划--网络模块NSURLSession概述

目录

  • 前言
  • 概述
  • NSURLRequest
  • NSURLSessionConfiguration
  • NSURLSession
  • NSURLSessionTask
  • Deleagte
  • 一些其他的点
  • NSURLCache
  • NSURLResponse/NSHTTPURLResponse
  • NSURLCredential
  • NSURLAuthenticationChallenge
  • NSURLProtectionSpace

前言:

其实是第一次仔细的接触iOS的网络模块、当时培训的时候学过不过早就已经忘光了(现在只记得AFNetworking、比前端程序员依赖jQuery更甚)。

准备先了解个大概、然后再逐一深入。
所以本篇并没写Demo、也没有涉及太具体的请求代码。
旨在通过一篇文章能对NSURLSession了解个大概(最起码面试简单扯皮够用)
也整理了大部分相关的API、有兴趣可以自己翻阅(在本文最后)
然后本文主要的学习大纲是通过《IOS网络开发NSURLSession详解》整理的、推荐阅读


概述

对于iOS而言、网络变成主要依赖两种方式:NSURLSession以及NSURLConnection。对于NSURLConnection、我入行甚至培训iOS的时候、就淘汰并且被NSURLSession取代了。也不太有精力学一个已经废弃的东西就为了写点东西、所以没啥可说的(如果有精力可以去找一篇总结二者区别比较全面的贴出来)。

咳、简单总结一下:
1、下载任务时:
NSURLConnection会先放在内存、最后写入沙盒。可能引起内存暴涨。
NSURLSession会直接写在沙盒和tem文件夹中、最后需要手动转移。
2、请求控制:
NSURLConnection创建好了对象、便开始网络请求。
只能cancel并不能恢复。
NSURLSession则在挂起状态需要手动resume。
可以取消(cancel)、暂停(suspend)、继续(resume)。
3、断点续传:
NSURLConnection通过设置访问请求的HTTPHeaderField的Range属性、继续下载剩余的部分。
NSURLSession通过将任务暂停时候代理返回的resumeData传入downloadTaskWithResumeData:方法进行续传。
4、配置信息:
NSURLConnection只能全局配置。
NSURLSession每一个实例都可以通过NSURLSessionConfiguration进行配置。

详阅:《NSURLSession与NSURLConnection区别》

了解NSURLSession的话。该从哪里切入呢?写一个网络请求就知道了

- (void)NSURLSessionTest {
    
    /******1、NSURLRequest********/
    NSString *urlString = @"http://api.androidhive.info/volley/person_object.json";
    urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    NSURL *url = [NSURL URLWithString:urlString];
    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30];
    
    /******2、NSURLSessionConfiguration********/
    NSURLSessionConfiguration * configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    /******3、NSURLSession********/
    NSURLSession *sharedSession = [NSURLSession sessionWithConfiguration:configuration];

    /******4、NSURLSessionTask********/
    NSURLSessionDataTask *dataTask = [sharedSession dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error == nil) {
            NSLog(@"data=%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
        } else {
            NSLog(@"error=%@",error);
        }
    }];
    [dataTask resume];
}

很直观的、至少有四个部分:NSURLRequestNSURLSessionConfigurationNSURLSession以及NSURLSessionTask
但实际上有一个很重要的部分----代理、他可以比block细致的多的管理我们的网络请求。
所以主要是五个部分。


NSURLRequest

  • NSURLRequest

两种创建方式
1、直接通过NSURL创建:
默认超时60s、缓存策略NSURLRequestUseProtocolCachePolicy

+ (instancetype)requestWithURL:(NSURL *)URL;
- (instancetype)initWithURL:(NSURL *)URL;

2、通过NSURL超时时间缓存策略共同创建:

+ (instancetype)requestWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval;
- (instancetype)initWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval;

不论哪种方式、默认都是通过Get方式传输。

你可以通过NSURLRequest的属性获取很多相关的信息:
包括超时时间、请求的URL、缓存目录、是否支持蜂窝网络等等。
需要注意的是这些都是readonly、不能被修改。
但是对于比如请求方式、请求头、请求体、cookie等HTTP方面的属性。是可以修改的(iOS为NSURLRequest写了个NSHTTPURLRequest扩展、这种思路其实可以借鉴一下)

  • NSMutableURLRequest

顾名思义、他可以修改绝大部分(或者应该说是所有?我并没有逐个去查找对比、但是绝大部分平时用得到的东西都是能修改的)属性。


NSURLSessionConfiguration

NSURLSession提供一个配置策略、NSURLSession在初始化时会copyNSURLSessionConfiguration。所以如果需要不同的策略、需要不同的Configuration来生成新的session。
通常的使用就是以下三种:

  • @property (class, readonly, strong) NSURLSessionConfiguration *defaultSessionConfiguration;
    默认配置:会将缓存、钥匙串、cookie都保存下来。
  • @property (class, readonly, strong) NSURLSessionConfiguration *ephemeralSessionConfiguration;
    可以看错无痕浏览:所有东西随着session的废弃而废弃。

(说句题外话、defaultSessionConfigurationephemeralSessionConfiguration看其他帖子好像以前是类方法、原来还有class这种写法、为啥非要这么写呢、没发现什么必要性)

  • +(NSURLSessionConfiguration*)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier
    正常来讲APP在退出到后台的时候、网络传输将会停止。
    但通过background配置的session、当APP被切入后台的时候依旧可以进行网络会话。
    甚至进程被关闭后重新开启、只要有同一个identifier、也能继续会话(这不就是断点续传么?)。
除此之外、NSURLSessionConfiguration还可以配置很多东西。

比如:请求头信息、传输的类型、是否允许蜂窝传输、超时时间、cookie的控制、证书的存储、缓存(NSURLCache)、缓存策略(NSURLRequestCachePolicy)、最大连接数等等。

需要注意的是

NSURLSessionConfiguration所能配置的策略、有一些和NSURLRequest能配置的会冲突。
这时候、会优先使用NSURLRequest中的配置(比如超时、请求头等等)。


NSURLSession

NSURLSession是iOS网络会话的最核心模块。
由NSURLSessionConfiguration来配置、针对NSURLRequest创建出NSURLSessionTask进行网络会话。

其本身不进行网络会话的工作。但是通过代理或者block的方式、可以捕获网络会话的不同状态并加以处理。

  • 产出task、并通过block捕获最终状态
//生成session
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
//产出task
NSURLSessionDataTask * dataTask = [session dataTaskWithURL:[NSURL URLWithString:imageURL] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
  //taks完成
}];
//开始task
[dataTask resume];
  • 直接产出task、并且通过代理控制
//生成session并绑定代理
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
//产出task
NSURLSessionDataTask * dataTask = [session dataTaskWithURL:[NSURL URLWithString:imageURL]];
//开始task
[dataTask resume];

/* 
  各种各样的代理、包括session(`证书、重定向`)方面
  以及task(`链接成功、每次buffer的返回、传输完毕等等`)方面
*/

NSURLSessionTask

偷一张图



简单明了、NSURLSessionTask本身是个抽象类、不进行任何工作。

  • DataTask:
    用来请求资源、后台模式下不支持。

  • Upload Task:
    基于DataTask、但是提供了request body可以传递具体的文件或者二进制Data。后台模式下也支持Upload Task。

  • Download Task:
    下载任务。所有模式的session都支持。

  • 需要注意的是:

创建出的所有task都是在挂起状态的、需要[dataTask resume];手动开启。具体的创建方式可以参阅《iOS基础深入补完计划--NSURLSession相关API》中关于task创建的API。


Deleagte

代理是很大的一块、准备在开一篇帖子写几个Demo把每个代理都用一遍看看。
简单来讲:

  • NSURLSessionDelegate
    针对整体网络会话:证书、重定向等
  • NSURLSessionTaskDelegate
    针对网络任务:开始、结束、单次proposedResponse等
  • NSURLSessionDownloadDelegate
    针对下载任务的特殊代理
  • NSURLSessionStreamDelegate
    为数据流上传提供数据源的特殊代理

其实这些代理都是NSURLSessionDelegate的子类或者子子类、只是为了分工更加明确罢了。

详情可以参阅《iOS基础深入补完计划--NSURLSession代理使用详解(附Demo)》


一些其他的点


NSURLCache

  • 在IOS应用程序开发中、为了减少与服务端的交互次数、加快用户的响应速度、一般都会在IOS设备中加一个缓存的机制。使用缓存的目的是为了使用的应用程序能更快速的响应用户输入、是程序高效的运行。有时候我们需要将远程web服务器获取的数据缓存起来、减少对同一个url多次请求。使用sdk中的NSURLCache类、可以很方便的实现此功能。

  • NSURLCache可以做到完全的离线缓存、即在没有网络的情况下打开离线内容。通过自定义的实现、将缓存文件存放到沙盒路径下、缓存空间没有大小限制。可以借鉴H5离线缓存中的Manifest文件,来定义缓存策略。Manifest文件从服务器端下载下来,在本地做版本对比,来实现存储和更新。

  • NSURLCache拦截不到WKWebView中发出的任何网络请求。所以如果使用WKWebView的话、NSURLCache实现不了离线缓存的功能。

  • 可以通过NSURLSessionConfiguration的requestCachePolicy属性进行session层面的整体配置。也可以通过NSURLRequest/NSMutableURLRequest对单一请求进行配置。

更多的使用可以移步:《NSURLCache缓存使用简介》


NSURLResponse/NSHTTPURLResponse

网络请求的返回信息。


NSURLCredential

证书对象、有三种验证方式


NSURLAuthenticationChallenge

在访问资源的时候、可能服务器会返回需要授权(需要我们提供一个NSURLCredential对象)、会走以下两个代理:

//服务器验证客户端证书时:(`initWithIdentity`)
//客户端验证服务器证书时:(`initWithTrust`)
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler;

具体的写法可以看看《关于ios项目绕过证书访问https》

需要的授权信息会保存在这个类的对象里。
几个常用的属性

  • error
    最后一次授权失败的错误信息
  • failureResponse
    最后一次授权失败的错误信息
  • previousFailureCount
    授权失败的次数
  • proposedCredential
    建议使用的证书
  • protectionSpace
    NSURLProtectionSpace对象,包括了地址端口等信息。

NSURLProtectionSpace

这个类的对象代表了服务器上的一块需要授权信息的区域、英文叫realm。通过这个对象的信息来响应Challenge。
比如、如果服务器需要一个基于用户名密码的认证、那么应该先参考下NSURLProtectionSpace对象的host、port、realm、protocol等信息、然后依照这个信息提供证书。
大概的结构是这样:(都是可以取出来看的、依旧是只读)

NSURLProtectionSpace *defaultSpace = [[NSURLProtectionSpace alloc] initWithHost:@"yourbankingdomain.com"  
                                                                           port:443  
                                                                       protocol:NSURLProtectionSpaceHTTPS  
                                                                          realm:@"mobile"  
                                                           authenticationMethod:NSURLAuthenticationMethodDefault]; 

参考资料

官方文档
IOS网络开发NSURLSession详解--主要的学习大纲就是通过这篇文章整理的、推荐阅读
iOS网络NSURLSession使用详解
iOS基础深入补完计划--NSURLSessionConfiguration相关API
iOS基础深入补完计划--NSURLRequest/NSURLResponse相关API
iOS基础深入补完计划--NSURLSession相关API
iOS基础深入补完计划--证书与验证相关API
NSURLCache缓存使用简介
NSURLSession与NSURLConnection区别

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • 在苹果彻底弃用NSURLConnection之后自己总结的一个网上的内容,加上自己写的小Demo,很多都是借鉴网络...
    付寒宇阅读 4,268评论 2 13
  • iOS开发系列--网络开发 概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博、微信等,这些应用本身可...
    lichengjin阅读 3,648评论 2 7
  • 1.移动互联网时代,工具型产品的整体焦虑 简评:支付宝为什么一定要做社交?这背后,工具型产品面临着共同的瓶颈——变...
    何夕一言堂阅读 376评论 0 1
  • 错把昨天当今天,告别一圈结果还要再赖一天…… 今天蛋蛋说班里要求学唱《同一首歌》,选20个人最后参加表演。这实在是...
    潘语阅读 363评论 0 6
  • import UIKit class ViewController: UIViewController { @IB...
    hope7th阅读 520评论 0 0