2013年苹果全球开发者大会上(WWDC2013)发布的iOS7系统中推出的NSURLSession,是对NSURLConnection替代者。从iOS9开始,NSURLConnection中发送请求的两个方法已经过期(同步请求,异步请求),初始化网络连接的方法也被设置为过期,系统不再推荐使用,建议使用NSURLSession发送网络请求。
- (nullable instancetype)initWithRequest:(NSURLRequest *)request delegate:(nullable id)delegate startImmediately:(BOOL)startImmediately API_DEPRECATED("Use NSURLSession (see NSURLSession.h)", macos(10.5,10.11), ios(2.0,9.0), tvos(9.0,9.0)) __WATCHOS_PROHIBITED;
- (nullable instancetype)initWithRequest:(NSURLRequest *)request delegate:(nullable id)delegate API_DEPRECATED("Use NSURLSession (see NSURLSession.h)", macos(10.3,10.11), ios(2.0,9.0), tvos(9.0,9.0)) __WATCHOS_PROHIBITED;
+ (nullable NSURLConnection*)connectionWithRequest:(NSURLRequest *)request delegate:(nullable id)delegate API_DEPRECATED("Use NSURLSession (see NSURLSession.h)", macos(10.3,10.11), ios(2.0,9.0), tvos(9.0,9.0)) __WATCHOS_PROHIBITED;
@interface NSURLConnection (NSURLConnectionSynchronousLoading)
/*!
@method sendSynchronousRequest:returningResponse:error:
@abstract
Performs a synchronous load of the given request,
returning an NSURLResponse in the given out
parameter.
@discussion
A synchronous load for the given request is built on
top of the asynchronous loading code made available
by the class. The calling thread is blocked while
the asynchronous loading system performs the URL load
on a thread spawned specifically for this load
request. No special threading or run loop
configuration is necessary in the calling thread in
order to perform a synchronous load. For instance,
the calling thread need not be running its run loop.
@param
request The request to load. Note that the request is
deep-copied as part of the initialization
process. Changes made to the request argument after
this method returns do not affect the request that is
used for the loading process.
@param
response An out parameter which is filled in with the
response generated by performing the load.
@param
error Out parameter (may be NULL) used if an error occurs
while processing the request. Will not be modified if the
load succeeds.
@result The content of the URL resulting from performing the load,
or nil if the load failed.
*/
+ (nullable NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse * _Nullable * _Nullable)response error:(NSError **)error API_DEPRECATED("Use [NSURLSession dataTaskWithRequest:completionHandler:] (see NSURLSession.h", macos(10.3,10.11), ios(2.0,9.0), tvos(9.0,9.0)) __WATCHOS_PROHIBITED;
@end
@interface NSURLConnection (NSURLConnectionQueuedLoading)
/*!
@method sendAsynchronousRequest:queue:completionHandler:
@abstract
Performs an asynchronous load of the given
request. When the request has completed or failed,
the block will be executed from the context of the
specified NSOperationQueue.
@discussion
This is a convenience routine that allows for
asynchronous loading of an url based resource. If
the resource load is successful, the data parameter
to the callback will contain the resource data and
the error parameter will be nil. If the resource
load fails, the data parameter will be nil and the
error will contain information about the failure.
@param
request The request to load. Note that the request is
deep-copied as part of the initialization
process. Changes made to the request argument after
this method returns do not affect the request that
is used for the loading process.
@param
queue An NSOperationQueue upon which the handler block will
be dispatched.
@param
handler A block which receives the results of the resource load.
*/
+ (void)sendAsynchronousRequest:(NSURLRequest*) request
queue:(NSOperationQueue*) queue
completionHandler:(void (^)(NSURLResponse* _Nullable response, NSData* _Nullable data, NSError* _Nullable connectionError)) handler API_DEPRECATED("Use [NSURLSession dataTaskWithRequest:completionHandler:] (see NSURLSession.h", macos(10.7,10.11), ios(5.0,9.0), tvos(9.0,9.0)) __WATCHOS_PROHIBITED;
@end
支持的协议
- 支持data, ftp, http(s)协议, 同时支持代理服务器和socks网关.
- 支持http/1.1, http/2, spdy协议, 但同时需要服务器支持ALPN(Application Layer Protocol Negotiation,应用层协议协商)和NPN(Next Protocol Negotiation,下一代协议协商).
在 NSURLSession 在 iOS9 上自动支持 HTTP/2,无需其他配置.
HTTP/2 与 HTTP/1.1相比主要区别有:
- 每个 Host 只需一个 TCP connection;
- 连接多路复用(HTTP/1.0 中一个连接一次只能有一个请求、HTTP/1.1 中一个连接同时可以有多个请求,但一次只能有一个响应,HTTP/2则完全是多路复用的);
- request 可以设置优先级;
- 二进制协议(HTTP:超文本传输协议,以前是文本协议);
- 头部压缩;
- 服务器可以主动 push;
下载优化
NSURLConnection下载文件时,先是将整个文件下载到内存,然后再写入到沙盒,如果文件比较大,就会出现内存暴涨的情况。
NSURLSessionUploadTask下载文件时,会默认下载到沙盒中的tmp文件中,不会出现内存暴涨的情况 。下载完成后会把tmp中的临时文件删除,需要在初始化任务方法时,在completionHandler回调中增加保存文件的代码。
任务调度
NSURLConnection对象实例化之后,默认请求就发送(同步发送),不需要调用start方法。通过cancel停止请求的发送,停止后不能继续访问,需要创建新的请求。
NSURLSession有三个控制方法,取消(cancel)、暂停(suspend)、继续(resume),暂停以后可以通过继续恢复当前的请求任务。
后台下载和上传
NSURLSession要实现后台传输服务,可以通过[NSURLSessionConfiguration backgroundSessionConfiguration]来创建一个会话配置。添加到后台会话的任务在app进程外部运行,即使应用程序被挂起,崩溃,或者被杀死,它依然会运行。
NSURLSessionConfiguration *config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.flyelephant.backgroundSessionIdentifier"];
_backgroundSession = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
网络配置
@property (class, readonly, strong) NSURLSessionConfiguration *defaultSessionConfiguration;
@property (class, readonly, strong) NSURLSessionConfiguration *ephemeralSessionConfiguration;
+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));
NSURLSession在初始化时会把配置它的NSURLSessionConfiguration对象进行一次 copy,并保存到自己的configuration属性中,而且这个属性是只读的。因此之后再修改最初配置session的那个configuration对象对于session是没有影响的。
NSURLSessionConfiguration提供了三个方法来创建Session Configuration对象:
- defaultSessionConfiguration:该方法返回创建的一个默认Session Configuration对象。默认的Session Configuration会使用磁盘来缓存数据并在用户的keychain中存储凭证。它同样会存储cookie。
- ephemeralSessionConfiguration:返回一个session configuration,且不会使用缓存,cookie和凭证。使用ephemeral sessions主要的优点就是隐私。因此,它可以用于实现像秘密浏览这种功能。
- backgroundSessionConfigurationWithIdentifier::返回一个后台的session configuration。后台session不同于常规的,普通的session,它甚至可以在应用程序挂起,退出或者崩溃的情况下运行上传和下载任务。初始化时指定的标识符,被用于向任何可能在进程外恢复后台传输的守护进程(daemon)提供上下文。
参考资料
https://objccn.io/issue-5-4/
https://juejin.im/post/5c4ed0b0e51d4511dc730799
https://imtangqi.com/2016/04/01/from-nsurlconnection-to-nsurlsession/
https://www.jianshu.com/p/955307f6ddab