NSURLSession学习笔记(一)简介

1、URL Session的基本概念html

1.三种工做模式:ios

默认会话模式(default):工做模式相似于原来的NSURLConnection,使用的是基于磁盘缓存的持久化策略,使用用户keychain中保存的证书进行认证受权。缓存

瞬时会话模式(ephemeral):该模式不使用磁盘保存任何数据。全部和会话相关的caches,证书,cookies等都被保存在RAM中,所以当程序使会话无效,这些缓存的数据就会被自动清空。性能优化

后台会话模式(background):该模式在后台完成上传和下载,在建立Configuration对象的时候须要提供一个NSString类型的ID用于标识完成工做的后台会话。cookie


2.NSURLSession支持的三种任务网络

NSURLSession类支持三种类型的任务:加载数据,下载和上传。session


2、相关的类app

NSURLConnection这个名字,实际上指的是一组构成Foundation框架中URL加载系统的相互关联的组件:NSURLRequest,NSURLResponse,NSURLProtocol,NSURLCache,NSHTTPCookieStorage,NSURLCredentialStorage,以及和它同名的NSURLConnection。
框架

在WWDC 2013中,Apple的团队对NSURLConnection进行了重构,并推出了NSURLSession做为替代。async

NSURLSession也是一组相互依赖的类,它的大部分组件和NSURLConnection中的组件相同如NSURLRequest,NSURLCache等。而NSURLSession的不一样之处在于,它将NSURLConnection替换为NSURLSession和NSURLSessionConfiguration,以及3个NSURLSessionTask的子类:NSURLSessionDataTask, NSURLSessionUploadTask, 和NSURLSessionDownloadTask。


下面来讲下NSURLSession新推出的类:

1.NSURLSessionConfiguration类

其中NSURLSessionConfiguration用于配置会话的属性,能够经过该类配置会话的工做模式:


+ (NSURLSessionConfiguration *)defaultSessionConfiguration;  
+ (NSURLSessionConfiguration *)ephemeralSessionConfiguration;  
+ (NSURLSessionConfiguration *)backgroundSessionConfiguration:(NSString *)identifier;


在backgroundSessionConfiguration:方法中的identifier参数指定了会话的ID,用于标记后台的session。

该类的其中两个属性:

/* allow request to route over cellular. */  
@property BOOL allowsCellularAccess;  
  
/* allows background tasks to be scheduled at the discretion of the system for optimal performance. */  
@property (getter=isDiscretionary) BOOL discretionary NS_AVAILABLE(NA, 7_0);


allowsCellularAccess 属性指定是否容许使用蜂窝链接, discretionary属性为YES时表示当程序在后台运做时由系统本身选择最佳的网络链接配置,该属性能够节省经过蜂窝链接的带宽。在使用后台传输数据的时候,建议使用discretionary属性,而不是allowsCellularAccess属性,由于它会把WiFi和电源可用性考虑在内。补充:这个标志容许系统为分配任务进行性能优化。这意味着只有当设备有足够电量时,设备才经过Wifi进行数据传输。若是电量低,或者只仅有一个蜂窝链接,传输任务是不会运行的。后台传输老是在discretionary模式下运行。


2.NSURLSession类

获取NSURLSession类对象有几种方式:

/*
 * The shared session uses the currently set global NSURLCache,
 * NSHTTPCookieStorage and NSURLCredentialStorage objects.
 */
+ (NSURLSession *)sharedSession;
/*
 * Customization of NSURLSession occurs during creation of a new session.
 * If you only need to use the convenience routines with custom
 * configuration options it is not necessary to specify a delegate.
 * If you do specify a delegate, the delegate will be retained until after
 * the delegate has been sent the URLSession:didBecomeInvalidWithError: message.
 */
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(id <NSURLSessionDelegate>)delegate delegateQueue:(NSOperationQueue *)queue;


第一种方式是使用静态的sharedSession方法,该类使用共享的会话,该会话使用全局的Cache,Cookie和证书。

第二种方式是经过sessionWithConfiguration:方法建立对象,也就是建立对应配置的会话,与NSURLSessionConfiguration合做使用。

第三种方式是经过sessionWithConfiguration:delegate:delegateQueue方法建立对象,二三两种方式能够建立一个新会话并定制其会话类型。该方式中指定了session的委托和委托所处的队列。当再也不须要链接时,能够调用Session的invalidateAndCancel直接关闭,或者调用finishTasksAndInvalidate等待当前Task结束后关闭。这时Delegate会收到URLSession:didBecomeInvalidWithError:这个事件。Delegate收到这个事件以后会被解引用。


3.NSURLSessionTask类

NSURLSessionTask是一个抽象子类,它有三个子类:NSURLSessionDataTask,NSURLSessionUploadTask和NSURLSessionDownloadTask。这三个类封装了现代应用程序的三个基本网络任务:获取数据,好比JSON或XML,以及上传和下载文件。

下面是其继承关系:


有多种方法建立对应的任务对象:

(1)NSURLSessionDataTask

经过request对象或url建立:

/* 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. */  
- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url;


经过request对象或url建立,同时指定任务完成后经过completionHandler指定回调的代码块:

 /* 
 * 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. 
 */  
- (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;


(2)NSURLSessionUploadTask

经过request建立,在上传时指定文件源或数据源。

/* Creates an upload task with the given request.  The body of the request will be created from the file referenced by 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. */  
- (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. */  
- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request;


在建立upload task对象时,经过completionHandler指定任务完成后的回调代码块:

/* 
 * upload convenience method. 
 */  
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;  
- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData completionHandler:(void (^)(NSData *data, NSURLResponse *response, NSError *error))completionHandler;


(3)NSURLSessionDownloadTask

/* Creates a download task with the given request. */  
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request;  
  
/* Creates a download task to download the contents of the given 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. */  
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData;


下载任务支持断点续传,第三种方式是经过以前已经下载的数据来建立下载任务。
一样地能够经过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. 
 */  
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURL *location, NSURLResponse *response, NSError *error))completionHandler;  
- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSURL *location, NSURLResponse *response, NSError *error))completionHandler;  
- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData completionHandler:(void (^)(NSURL *location, NSURLResponse *response, NSError *error))completionHandler;


4.NSURLSessionDelegate和NSURLSessionTaskDelegate协议

在协议的方法中能够完成各类各样的回调动做,如身份验证、完成任务后的动做、错误处理和后台任务完成的动做等。委托方法指定在NSURLSession中必定数量的字节传输使用int64_t类型的参数。

这里只说下后台任务的一个委托方法:

/* If an application has received an 
 * -application:handleEventsForBackgroundURLSession:completionHandler: 
 * message, the session delegate will receive this message to indicate 
 * that all messages previously enqueued for this session have been 
 * delivered.  At this time it is safe to invoke the previously stored 
 * completion handler, or to begin any internal updates that will 
 * result in invoking the completion handler. 
 */  
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session NS_AVAILABLE_IOS(7_0);


合做使用的ApplicationDelegate方法:

// Applications using an NSURLSession with a background configuration may be launched or resumed in the background in order to handle the  
// completion of tasks in that session, or to handle authentication. This method will be called with the identifier of the session needing  
// attention. Once a session has been created from a configuration object with that identifier, the session's delegate will begin receiving  
// callbacks. If such a session has already been created (if the app is being resumed, for instance), then the delegate will start receiving  
// callbacks without any action by the application. You should call the completionHandler as soon as you're finished handling the callbacks.  
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler NS_AVAILABLE_IOS(7_0);


将任务切换到后台以后,Session的Delegate不会再收到和Task相关的消息。当全部Task全都完成后,程序将被唤醒,并调用ApplicationDelegate的application:handleEventsForBackgroundURLSession:completionHandler:回调,在这里要为后台session(由background session的identifier标识)指定对应的回调代码块。

随后,对于每个完成的后台Task调用该Session的Delegate中的URLSession:downloadTask:didFinishDownloadingToURL:(成功的话)和URLSession:task:didCompleteWithError:(成功或者失败都会调用)方法作处理,以上的回调代码块能够在这里调用。



本文参考的资料包括:

iOS 7系列译文:忘记NSURLConnection,拥抱NSURLSession吧!

NSURLSession使用说明及后台工做流程分析

Using NSURLSession

objc.io #5 iOS 7 From NSURLConnection to NSURLSession

相关文章
相关标签/搜索