与 NSURLConnection 相比,NSURLsession 最直接的改进就是能够配置每一个 session 的缓存,协议,cookie,以及证书策略(credential policy),甚至跨程序共享这些信息。这将容许程序和网络基础框架之间相互独立,不会发生干扰。每一个 NSURLSession 对象都由一个 NSURLSessionConfiguration 对象来进行初始化,后者指定了刚才提到的那些策略以及一些用来加强移动设备上性能的新选项。
NSURLSession 中另外一大块就是 session task。它负责处理数据的加载以及文件和数据在客户端与服务端之间的上传和下载。NSURLSessionTask 与 NSURLConnection 最大的类似之处在于它也负责数据的加载,最大的不一样之处在于全部的 task 共享其创造者 NSURLSession 这一公共委托者(common delegate)。
NSURLSession
NSURLSession 是 iOS 7 新引入的用于替代 NSURLConnection 的类。
NSURLSession提供的功能:
1.经过URL将数据下载到内存
2.经过URL将数据下载到文件系统
3.将数据上传到指定URL
4.在后台完成上述功能
1.建立一个NSURLSessionConfiguration,用于第二步建立NSSession时设置工做模式和网络设置:
工做模式分为:
通常模式(default):工做模式相似于原来的NSURLConnection,可使用缓存的Cache,Cookie,鉴权。
及时模式(ephemeral):不使用缓存的Cache,Cookie,鉴权。
后台模式(background):在后台完成上传下载,建立Configuration对象的时候须要给一个NSString的ID用于追踪完成工做的Session是哪个(后面会讲到)。
网络设置:参考NSURLConnection中的设置项。
1. 建立一个NSURLSession,系统提供了两个建立方法:
sessionWithConfiguration:
sessionWithConfiguration:delegate:delegateQueue:
第一个粒度较低就是根据刚才建立的Configuration建立一个Session,系统默认建立一个新的OperationQueue处理Session的消息。
第二个粒度比较高,能够设定回调的delegate(注意这个回调delegate会被强引用),而且能够设定delegate在哪一个OperationQueue回调,若是咱们将其设置为[NSOperationQueue mainQueue]就能在主线程进行回调很是的方便。
2.建立一个NSURLRequest调用刚才的NSURLSession对象提供的Task函数,建立一个NSURLSessionTask。
NSURLSessionConfiguration * config=[NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession * session=[NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
NSURL *url=[NSURL URLWithString:@src];
NSURLRequest * request=[NSURLRequest requestWithURL:url];
NSURLSessionDownloadTask *task= [_session downloadTaskWithRequest:_request];
[_task resume];
根据职能不一样Task有三种子类:
NSURLSessionUploadTask:上传用的Task,传完之后不会再下载返回结果;
NSURLSessionDownloadTask:下载用的Task;
NSURLSessionDataTask:能够上传内容,上传完成后再进行下载。
3.若是是细粒度的Session调用,Session与Delegate会在指定的OperationQueue中进行交互,以我们下载例子,交互过程的顺序图以下(假如不须要鉴权,即非HTTPS请求):
4.当再也不须要链接调用Session的invalidateAndCancel直接关闭,或者调用finishTasksAndInvalidate等待当前Task结束后关闭。这时Delegate会收到URLSession:didBecomeInvalidWithError:这个事件。Delegate收到这个事件以后会被解引用。
NSURLSession相关的类
NSURLConnection这个名字,实际上指的是一组构成Foundation框架中URL加载系统的相互关联的组件:NSURLRequest,NSURLResponse,NSURLProtocol,NSURLCache,NSHTTPCookieStorage,NSURLCredentialStorage,以及和它同名的NSURLConnection。
在WWDC2013中,Apple的团队对NSURLConnection进行了重构,并推出了NSURLSession做为替代。
NSURLSession也是一组相互依赖的类,它的大部分组件和NSURLConnection中的组件相同如NSURLRequest,NSURLCache等。而NSURLSession的不一样之处在于,它将NSURLConnection替换为NSURLSession和NSURLSessionConfiguration,以及3个NSURLSessionTask的子类:NSURLSessionDataTask, NSURLSessionUploadTask, 和NSURLSessionDownloadTask。
NSURLSessionConfiguration
NSURLSessionConfiguration用于配置会话的属性,能够经过该类配置会话的工做模式:
+ (NSURLSessionConfiguration *)defaultSessionConfiguration;
+ (NSURLSessionConfiguration *)ephemeralSessionConfiguration;
+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier NS_AVAILABLE(10_10, 8_0);
方法中的identifier参数指定了会话的ID,用于标记后台的session。
@property BOOL allowsCellularAccess;//是否容许使用蜂窝链接
@property (getter=isDiscretionary) BOOL discretionary NS_AVAILABLE(10_10, 7_0);
discretionary=yes 表示当程序在后台运做时由系统本身选择最佳的网络链接配置,该属性能够节省经过蜂窝链接的带宽。建议使用discretionary属性,而不是allowsCellularAccess属性,由于它会把WiFi和电源可用性考虑在内。
NSURLSession
+ (NSURLSession *)sharedSession;
使用静态的sharedSession方法,该类使用共享的会话,该会话使用全局的Cache,Cookie和证书。
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;
方法建立对象,也就是建立对应配置的会话,与NSURLSessionConfiguration合做使用。
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;
经过sessionWithConfiguration:delegate:delegateQueue方法建立对象,二三两种方式能够建立一个新会话并定制其会话类型。该方式中指定了session的委托和委托所处的队列。当再也不须要链接时,能够调用Session的invalidateAndCancel直接关闭,或者调用finishTasksAndInvalidate等待当前Task结束后关闭。这时Delegate会收到URLSession:didBecomeInvalidWithError:这个事件。Delegate收到这个事件以后会被解引用。
NSURLSessionTask
NSURLSessionTask是一个抽象子类,它有三个子类:NSURLSessionDataTask,NSURLSessionUploadTask和NSURLSessionDownloadTask。这三个类封装了现代应用程序的三个基本网络任务:获取数据,好比JSON或XML,以及上传和下载文件。断点续传
当一个 NSURLSessionDataTask 完成时,它会带有相关联的数据,而一个 NSURLSessionDownloadTask 任务结束时,它会带回已下载文件的一个临时的文件路径。由于通常来讲,服务端对于一个上传任务的响应也会有相关数据返回,因此 NSURLSessionUploadTask 继承自 NSURLSessionDataTask。
不一样于直接使用 alloc-init 初始化方法,task 是由一个 NSURLSession 建立的。每一个 task 的构造方法都对应有或者没有 completionHandler 这个 block 的两个版本,例如:有这样两个构造方法 –dataTaskWithRequest: 和 –dataTaskWithRequest:completionHandler:。这与 NSURLConnection 的 -sendAsynchronousRequest:queue:completionHandler: 方法相似,经过指定 completionHandler 这个 block 将建立一个隐式的 delegate,来替代该 task 原来的 delegate——session。对于须要 override 原有 session task 的 delegate 的默认行为的状况,咱们须要使用这种不带 completionHandler 的版本。
NSURLConnection:
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { // ... }];
NSURLSession:
在 task 的构造方法上延续了这一模式。不一样的是,这里不会当即运行 task,而是将该 task 对象先返回,容许咱们进一步的配置,而后可使用 resume 方法来让它开始运行。
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler: ^(NSData *data, NSURLResponse *response, NSError *error) { // ... }];
[task resume];
Download task 也须要一个 request,不一样之处在于 completionHandler 这个 block。Data task 和 upload task 会在任务完成时一次性返回,可是 Download task 是将数据一点点地写入本地的临时文件。因此在 completionHandler 这个 block 里,咱们须要把文件从一个临时地址移动到一个永久的地址保存起来:
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithRequest:request completionHandler: ^(NSURL *location, NSURLResponse *response, NSError *error) {
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSURL *documentsDirectoryURL = [NSURL fileURLWithPath:documentsPath];
NSURL *newFileLocation = [documentsDirectoryURL URLByAppendingPathComponent:[[response URL] lastPathComponent]];
[[NSFileManager defaultManager] copyItemAtURL:location toURL:newFileLocation error:nil]; }];
[downloadTask resume];
downloadTaskWithResumeData 断点续传
+ (NSURLSessionConfiguration *)backgroundSessionConfiguration:(NSString *)identifier 后台下载
sessionWithConfiguration
NSURLSessionDownloadDelegate
为了实现下载进度的显示,须要在委托中的如下方法中实现:
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
didWriteData:(int64_t)bytesWritten
totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite;
double downloadProgress = totalBytesWritten / (double)totalBytesExpectedToWrite;
-------------------------------------
AFJSONRequestOperation 是 AFHTTPRequestOperation 的子类,针对 JSON 类型请求作了特殊处理,在有了 AFHTTPRequestOperation+AFURLConnectionOperation 的基础工做后,AFJSONRequestOperation 已经很是方便直接使用了。指定 acceptableContentTypes: 以支持 JSON,responseJSON 直接返回已经解析好的 JSON 数据对象。下载到 JSON 数据后在一单独线程
AFXMLRequestOperation/AFPropertyListRequestOperation/AFImageRequestOperation 和 AFJSONRequestOperation 相似,针对 XML、Plist、image 类型请求作了一些处理。其中 AFImageRequestOperation 额外有一个 imageProcessingBlock,取到图片后能够在一个单独线程 queque 对图片进行处理,好比缩放、切圆角、图片特效等,而后再交给 main_queue success block.
AFN 还提供了一个 UIImageView+AFNetworking category,能够用 setImageWithURL: 来设置图片。这个 cagetory 和 SDWebImage 相似但更简单一些,图片下载由 AFN 完成,图片缓存由 NSCache 处理。