标签:
NSURLSession是iOS7中新的网络接口,它与NSURLConnection是并列的。但是在iOS9中,苹果已经废除了NSURLConnection的使用,使用NSURLSession代替。AFNetworking最先版已经将NSURLConnection替换为NSURLSession。
参见:https://developer.apple.com/library/prerelease/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS9.html
在程序在前台时,NSURLSession与NSURLConnection可以互为替代工作。但是,如果用户强制将程序关闭,NSURLSession会断掉。
使用方法:
1.创建一个NSURLSessionConfiguration,为创建NSURLSession设置工作模式和网络;
一般模式(default):工作模式类似于原来的NSURLConnection,可以使用缓存的Cache,Cookie,鉴权。
及时模式(ephemeral):不使用缓存的Cache,Cookie,鉴权。
后台模式(background):在后台完成上传下载,创建Configuration对象的时候需要给一个NSString的ID用于追踪完成工作的Session是哪一个。
2.创建一个NSURLSession,方法有三种:
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;
这种方法根据刚才创建的sessionConfiguration创建session,并默认创建一个新的queue处理session信息
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration
delegate:(id<NSURLSessionDelegate>)delegate delegateQueue:(NSOperationQueue *)queue;
这种方法可以设置回调的delegate和queue,如果设置在mainQueue,就能在主线程进行回调。如果不指定线程,默认就是子线程。
注意:session对delegateQueue是强应用,如果不停止session或者退出应用,它会一直存在在内存中。
(NSURLSession *)sharedSession
这种方法创建的session,使用使用共享的会话,全局的Cache,Cookie和证书。但是:不能逐渐获取服务器数据、自定义连接行为受限、鉴权受限、app未运行情况下无法后台上传和下载。
3.创建一个NSURLRequest调用刚才的NSURLSession对象提供的Task函数,创建一个NSURLSessionTask。
根据职能不同Task有三种子类:
1)NSURLSessionUploadTask:上传用的Task,传完以后不会再下载返回结果;
通过request创建,在上传时指定文件源或数据源。
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL;
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData;
- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request;
在创建upload task对象时,通过completionHandler指定任务完成后的回调代码块:
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;
2)NSURLSessionDownloadTask:下载用的Task;
通过request对象或url创建:
- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url;
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request;
通过request对象或url创建,同时指定任务完成后通过completionHandler指定回调的代码块:
- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSURL *location, NSURLResponse *response, NSError *error))completionHandler;
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURL *location, NSURLResponse *response, NSError *error))completionHandler;
根据已经下载的数据,继续下载任务,也有直接创建和任务完成后通过completionHandler指定回调的代码块两种:
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData;
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData completionHandler:(void (^)(NSURL *location, NSURLResponse *response, NSError *error))completionHandler;
3)NSURLSessionDataTask:可以上传内容,上传完成后再进行下载。
通过request对象或url创建:
1 - (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request; 2 - (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url;
通过request对象或url创建,同时指定任务完成后通过completionHandler指定回调的代码块:
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;
如果是第二种方法创建的Session调用,Session与Delegate会在指定的OperationQueue中进行交互,交互过程的顺序图如下(假如不需要鉴权,即非HTTPS请求):
4.当不再需要连接时:
调用Session的invalidateAndCancel直接关闭,或者调用finishTasksAndInvalidate等待当前Task全部结束后关闭。这时Delegate会收到URLSession:didBecomeInvalidWithError:这个事件。Delegate收到这个事件之后会被解引用。
5.如果是一个BackgroundSession:在Task执行的时候,用户切到后台,Session会和ApplicationDelegate做交互。当程序切到后台后,在BackgroundSession中的Task还会继续下载,这部分文档叙述比较少,现在分三个场景分析下Session和Application的关系:
1)当加入了多个Task,程序没有切换到后台。
这种情况Task会按照NSURLSessionConfiguration的设置正常下载,不会和ApplicationDelegate有交互。
2)当加入了多个Task,程序切到后台,所有Task都完成下载。
在切到后台之后,Session的Delegate不会再收到Task相关的消息,直到所有Task全都完成后,系统会调用ApplicationDelegate的application:handleEventsForBackgroundURLSession:completionHandler:回调,之后“汇报”下载工作,对于每一个后台下载的Task调用Session的Delegate中的URLSession:downloadTask:didFinishDownloadingToURL:(成功的话)和URLSession:task:didCompleteWithError:(成功或者失败都会调用)
之后调用Session的Delegate回调URLSessionDidFinishEventsForBackgroundURLSession:。
注意:在ApplicationDelegate被唤醒后,会有个参数ComplietionHandler,这个参数是个Block,这个参数要在后面Session的Delegate中didFinish的时候调用一下,如下:
@implementation appDelegate
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler
{
self.backgroundSessionCompletionHandler = completionHandler;
}
标签:
原文地址:http://www.cnblogs.com/xiayao/p/5260227.html