URL的组成:html
通常状况是: 协议(scheme
)://主机名(host
):端口(port
)/服务器上资源的路径(path
)?参数ios
例子:http://100.0.0.0:8080/xxx?id=3macos
通用格式:协议://用户名(user
):密码(password
)@主机名:端口/服务器上资源的路径?参数#片断(fragment
)浏览器
例子:ftp://joe:joepasswd@ftp.prep.edu/pub/name/xxx?id=3#name缓存
协议(scheme):
http
https
ftp
等等
用户名和密码:不少服务器都要求输入用户名和密码才会容许用户访问数据,如FTP服务器。
主机名(host):://
后边的域名或者 ip。例如:htouhui.com
or100.0.0.0
端口(port)::
后边的8080 路径(path):端口后边的第一个/
开始到?
结束,路径说明了资源位于服务器的什么地方 参数:?
后边#
前边 例如id=3
片断(fragment):#
后边的,例如name
安全
NSUrlRequest 是封装了2个必要内容:URL和扩展服务器
URL:请求头,请求体,输入流,请求方法,超时时间等等
扩展:协议(Http https ftp 等等的成熟协议和自定义协议),缓存等等cookie
[注]:NSURLRequest
继承NSSecureCoding
协议,NSSecureCoding
的前身是NSCoding
,NSSecureCoding
更加安全,主要目的是:继承这个写协议的类能够和NSData互相转换。网络
缓存session
//缓存策略:
NSURLRequestUseProtocolCachePolicy = 0, //默认的缓存策略(取决于协议)
NSURLRequestReloadIgnoringLocalCacheData = 1, // 忽略缓存,从新请求
NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, // Unimplemented
NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData,
NSURLRequestReturnCacheDataElseLoad = 2, // 有缓存就用缓存,没有缓存就从新请求
NSURLRequestReturnCacheDataDontLoad = 3, // 有缓存就用缓存,没有缓存就不发请求,当作请求出错处理(用于离线模式)
NSURLRequestReloadRevalidatingCacheData = 5, // Unimplemented
复制代码
管理cookie全局缓存池
通常系统默认去管理这个对象,开发人员也能够管理(加载的时机由系统控制)
管理身份验证信息
2个子类
NSInternetPassword: 用户名和密码验证
NSClientCertificate: 证书验证
iOS 2 的时候推出的网络接口(iOS 9废除),接口比较少,实现了简单的功能,暂停,断点续传,监听进度等等的功能,自能开发人员本身去实现。
由上图咱们能够知道NSURLConnection
发送网络请求的工做流程:
NSURLRequest
对象被传递给NSURLConnection
对象.NSURLConnection
在NSURLCache
里边找,若是有直接返回NSURLResponse
.NSHTTPCookieStorage
里的cookie 和 NSURLCredentialStorage
里的身份验证信息,发送网络请求NSURLProtocol
的代理里边获得NSURLResponse
网络请求配置,包括会话类型,缓存,超时时间,缓存,cookie,认证配置
//会话类型为下边的3种
//默认会话类型,可以进行磁盘缓存
//他们使用永久性的基于磁盘的缓存并将凭证存储在用户的钥匙串
@property (class, readonly, strong) NSURLSessionConfiguration *defaultSessionConfiguration;
//临时会话类型,不进行任何的磁盘缓存
//全部的缓存,凭证存储等都保存在RAM中并与会话绑定。所以,当您的应用程序使会话失效时,它们会自动清除
@property (class, readonly, strong) NSURLSessionConfiguration *ephemeralSessionConfiguration;
//后台类型,用于后台下载上传
//与默认会话相似,不一样之处在于单独的进程处理全部数据传输
+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier;
//后台会话配置的标识符
@property (nullable, readonly, copy) NSString *identifier;
//超时时间
@property NSTimeInterval timeoutIntervalForRequest;
//ServiceType
@property NSURLRequestNetworkServiceType networkServiceType;
//是否使用流量
@property BOOL allowsCellularAccess;
//cookie 配置
@property NSHTTPCookieAcceptPolicy HTTPCookieAcceptPolicy;
@property (nullable, retain) NSHTTPCookieStorage *HTTPCookieStorage;
//缓存配置
@property NSURLRequestCachePolicy requestCachePolicy;
@property (nullable, retain) NSURLCache *URLCache;
//认证配置
@property (nullable, retain) NSURLCredentialStorage *URLCredentialStorage;
复制代码
NSURLSessionTask
有2个子类,继承关系以下图
NSURLSessionTask
是一个抽象类,若是要使用那么只能使用它的子类。
NSURLSessionDataTask
能够用来处理通常的网络请求,如 GET | POST 请求等。
NSURLSessionDataTask
有一个子类为 NSURLSessionUploadTask,用于处理上传请求的时候有优点。
NSURLSessionDownloadTask
主要用于处理下载请求,有很大的优点。
NSURLConnection
的升级版本,功能比前者强大太多,也支持Http的更高的版本,传输速度更快。
@interface NSURLSession : NSObject
/* sharedSession属性表示使用当前的全局的NSURLCache, NSHTTPCookieStorage 和 NSURLCredentialStorage对象。 */
@property (class, readonly, strong) NSURLSession *sharedSession;
/* * 构建方法 */
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;
//操做队列
@property (readonly, retain) NSOperationQueue *delegateQueue;
//代理
@property (nullable, readonly, retain) id <NSURLSessionDelegate> delegate;
//配置
@property (readonly, copy) NSURLSessionConfiguration *configuration;
/* * 能够提供对session 的标签描述 */
@property (nullable, copy) NSString *sessionDescription;
/* 当即返回,现有任务将被容许运行完成。 新任务可能没法建立。 会话将继续进行代理的回调,直到发布URLSession:didBecomeInvalidWithError:为止。 finishTasksAndInvalidate 和 invalidateAndCancel 对共享会话单例没有任何影响. 当使后台会话无效时,在URLSession:didBecomeInvalidWithError:已经发布以前,使用相同的标识符建立另外一个后台会话是不安全的。 */
- (void)finishTasksAndInvalidate;
/* 充当 finishTasksAndInvalidate,可是会针对此会话的全部未完成任务执行取消 cancel。 */
- (void)invalidateAndCancel;
- (void)resetWithCompletionHandler:(void (^)(void))completionHandler; /* empty all cookies, cache and credential stores, removes disk files, issues -flushWithCompletionHandler:. Invokes completionHandler() on the delegate queue if not nil. */
- (void)flushWithCompletionHandler:(void (^)(void))completionHandler; /* flush storage to disk and clear transient network caches. Invokes completionHandler() on the delegate queue if not nil. */
- (void)getTasksWithCompletionHandler:(void (^)(NSArray<NSURLSessionDataTask *> *dataTasks, NSArray<NSURLSessionUploadTask *> *uploadTasks, NSArray<NSURLSessionDownloadTask *> *downloadTasks))completionHandler; /* invokes completionHandler with outstanding data, upload and download tasks. */
- (void)getAllTasksWithCompletionHandler:(void (^)(NSArray<__kindof NSURLSessionTask *> *tasks))completionHandler API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); /* invokes completionHandler with all outstanding tasks. */
/* * NSURLSessionTask objects are always created in a suspended state and * must be sent the -resume message before they will execute. */
// NSURLSessionTask对象必须在暂停状态下建立,必须发送- resume消息才执行。
/* Creates a data task with the given request. The request may have a body stream. */
// 根据给定的请求建立数据任务,请求具备体流。
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request;
/* Creates a data task to retrieve the contents of the given URL. */
// 建立数据任务以检索给定URL的内容
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url;
/* Creates an upload task with the given request. The body of the request will be created from the file referenced by fileURL */
// 根据给定的请求建立一个给定的上传任务,请求体根据fileURL文件引用建立
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL;
/* Creates an upload task with the given request. The body of the request is provided from the bodyData. */
// 根据给定的请求,建立一个上传任务,请求体根据bodyData提供
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData;
/* Creates an upload task with the given request. The previously set body stream of the request (if any) is ignored and the URLSession:task:needNewBodyStream: delegate will be called when the body payload is required. */
// 根据给定的请求建立上传任务,忽略之前请求的体流设置,当须要加载体的时候,
// 将会调用URLSession:task:needNewBodyStream: 代理方法。
- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request;
/* Creates a download task with the given request. */
// 根据指定的请求建立下载任务
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request;
/* Creates a download task to download the contents of the given URL. */
// 建立下载任务,下载给定URL的内容
- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url;
/* Creates a download task with the resume data. If the download cannot be successfully resumed, URLSession:task:didCompleteWithError: will be called. */
// 根据resume data建立一个下载任务,若是下载不能成功开始,那么会调用URLSession:task:didCompleteWithError:
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData;
/* Creates a bidirectional stream task to a given host and port. */
// 建立给定主机和端口的双向流任务
- (NSURLSessionStreamTask *)streamTaskWithHostName:(NSString *)hostname port:(NSInteger)port API_AVAILABLE(macos(10.11), ios(9.0), tvos(9.0)) __WATCHOS_PROHIBITED;
/* Creates a bidirectional stream task with an NSNetService to identify the endpoint. * The NSNetService will be resolved before any IO completes. */
// 使用NSNetService识别端点以建立双向流任务。
// NSNetService将在任何IO完成以后解决
- (NSURLSessionStreamTask *)streamTaskWithNetService:(NSNetService *)service API_AVAILABLE(macos(10.11), ios(9.0), tvos(9.0)) __WATCHOS_PROHIBITED;
复制代码
分类 NSURLSessionAsynchronousConvenience
// NSURLSession便捷例程将结果传递给完成处理程序块。 这些便利例程不适用于配置为后台会话的NSURLSessions。
// 任务对象老是在挂起状态建立,而且必须在执行以前发送-resume消息。
@interface NSURLSession (NSURLSessionAsynchronousConvenience)
/* * data task convenience methods. These methods create tasks that * bypass the normal delegate calls for response and data delivery, * and provide a simple cancelable asynchronous interface to receiving * data. Errors will be returned in the NSURLErrorDomain, * see <Foundation/NSURLError.h>. The delegate, if any, will still be * called for authentication challenges. */
// 数据任务的便利方法。 这些方法建立绕过普通代理调用进行响应和数据传递的任务,
// 并提供一个简单的可取消异步接口来接收数据。 错误将在NSURLErrorDomain中返回,
// 请参阅<Foundation / NSURLError.h>。 代理(若是有的话)仍将被要求认证挑战。
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
/* * upload convenience method. */
// 上传任务便利化方法
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(nullable NSData *)bodyData completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
/* * download task convenience methods. When a download successfully * completes, the NSURL will point to a file that must be read or * copied during the invocation of the completion routine. The file * will be removed automatically. */
// 下载任务便利化方法,当成功下载完成时,URL指向一个文件,
// 这个文件必须在完成调用中进行读和赋值,文件将被自动移除。
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData completionHandler:(void (^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;
@end
复制代码
那么怎么理解这3个类呢? URLSession
是负责发送和接收请求的关键对象, URLSessionConfiguration
是URLSession
的配置参数,能够经过URLSessionConfiguration
来建立URLSession
;而URLSessionTask
是一次任务(会话),他是URLSession
的具体执行者。下图能够看到:
NSURLRequest
URLCache
NSHTTPCookieStorage
NSURLCredentialStorage
这些基本类来处理。NSURLSession
均可以单独配置 URLSessionConfiguration
NSURLConnection
使用异步回调,先将数据下载到内存,等下载完毕后,再写入沙盒.若是文件很大,会致使内存暴涨; 而且,使用异步回调没法监听下载进度.因此使用 NSURLConnection
下载的时候,使用代理回调监听下载进度,而且下载过程当中要手动管理内存(致使内存暴涨)
,使用起来比较麻烦.而使用NSURLSession
的时候,block
和代理能够同时起做用,而且能够直接从文件系统上传、下载,不会出现内存暴涨的状况. 下载文件的时候,默认会将文件下载到沙盒的 tmp文件夹中,不会占多少用内存. 可是在下载完成后,会删除文件,因此要在下载完成或者其余须要的地方,增长保存文件的代码.NSURLConnection
实例化对象,实例化开始,默认请求就发送(同步发送),不须要调用start
方法。而cancel
能够中止请求的发送,中止后不能继续访问,须要建立新的请求。NSURLSession
有三个控制请求的方法,取消(cancel
),暂停(suspend
),继续(resume
),暂停后能够经过继续恢复当前的请求任务。NSURLConnection
进行断点下载,经过设置访问请求的HTTPHeaderField
的Range
属性,开启运行循环,NSURLConnection
的代理方法做为运行循环的事件源,接收到下载数据时代理方法就会持续调用,并使用NSOutputStream
(或者经过文件指针)管道流进行数据保存。NSURLSession
进行断点下载,当暂停下载任务后,若是 downloadTask
(下载任务)为非空,调用cancelByProducingResumeData:(void (^)(NSData *resumeData))completionHandler
这个方法,这个方法接收一个参数,完成处理代码块,这个代码块有一个NSData
参数 resumeData
,若是resumeData
非空,咱们就保存这个对象到视图控制器的resumeData
属性中。在点击再次下载时,经过调用 [ [self.session downloadTaskWithResumeData: self.resumeData]resume]
方法进行继续下载操做。通过以上比较能够发现,使用NSURLSession
进行断点下载更加便捷。NSURLSession
能够设置配置信息 NSURLSession
的构造方法 (sessionWithConfiguration: delegate:delegateQueue
)中有一个 NSURLSessionConfiguration类的参数能够设置配置信息,其决定了cookie
,安全和高速缓存策略,最大主机链接数,资源管理,网络超时等配置。NSURLConnection
不能进行这个配置,相比于NSURLConnection
依赖于一个全局的配置对象,缺少灵活性而言,NSURLSession 有很大的改进了。 NSURLSession
能够设置三种配置信息,分别经过调用三个类方法返回配置对象: +(NSURLSessionConfiguration *) defaultSessionConfiguration
,配置信息使用基于硬盘的持久化Cache
,保存用户的证书到钥匙串,使用共享cookie
存储; +(NSURLSessionConfiguration *)ephemeralSessionConfiguration
配置信息和default
大体相同。除了,不会把cache
,证书,或者任何和Session
相关的数据存储到硬盘,而是存储在内存中,生命周期和Session
一致。好比浏览器无痕浏览等功能就能够基于这个来作; +(NSURLSessionConfiguration *) backgroundSessionConfigurationWithIdentifier:(NSString *)identifier
配置信息能够建立一个能够在后台甚至APP已经关闭的时候仍然在传输数据的session
。 注意,后台Session
必定要在建立的时候赋予一个惟一的identifier
,这样在APP下次运行的时候,可以根据identifier
来进行相关的区分。若是用户关闭了APP,IOS 系统会关闭全部的background Session
。并且,被用户强制关闭了之后,IOS系统不会主动唤醒APP,只有用户下次启动了APP,数据传输才会继续。参考文章:
www.jianshu.com/p/2d4d1d7df…
www.cnblogs.com/1018475062q…
cloud.tencent.com/developer/a…
www.jianshu.com/p/877dec053…