AFNetworking 知识点1NSURLSession

NSURLSession
NSURLConnection 和 NSURLsession 的不同:
与 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,以及上传和下载文件。断点续传

http://blog.csdn.net/mhttp://objccn.io/issue-5-4/

http://objccn.io/issue-5-4/

当一个 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:
NSURL *URL = [NSURL URLWithString:@"http://example.com"]; 
NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { // ... }];
NSURLSession:
在 task 的构造方法上延续了这一模式。不同的是,这里不会立即运行 task,而是将该 task 对象先返回,允许我们进一步的配置,然后可以使用 resume 方法来让它开始运行。
 
NSURL *URL = [NSURL URLWithString:@"http://example.com"]; 
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 里,我们需要把文件从一个临时地址移动到一个永久的地址保存起来:
 
NSURL *URL = [NSURL URLWithString:@"http://example.com/file.zip”];
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 处理。
 
posted @ 2018-03-30 19:45  我是你们最爱的硕哥  阅读(248)  评论(0编辑  收藏  举报