美文网首页杂的文好文章收藏夹
详细解析几个和网络请求有关的类 (一) —— NSURLSess

详细解析几个和网络请求有关的类 (一) —— NSURLSess

作者: 刀客传奇 | 来源:发表于2018-03-08 00:18 被阅读129次

    版本记录

    版本号 时间
    V1.0 2018.03.08

    前言

    我们做APP发起网络请求,一般都是使用框架,这些框架的底层也都是苹果的API,接下来几篇就一起来看一下和网络有关的几个类。

    NSURLSession

    这个类是网络请求相关的最重要的类,可以说是网络请求的基础,任何请求都是在一个特定的会话中完成的。

    NSURLSessionNSURLConnection的替代API。它提供影响政策的各种选择,以及各方面的政策从中检索NSURLRequest对象的机制网络。

    NSURLSession可以绑定到代理对象。代理是在会话的整个生命周期中为某些事件调用,例如服务器认证或确定是否加载资源应该转换成下载。

    NSURLSession实例是线程安全的。

    默认的NSURLSession使用系统提供的代理并且是适合用来代替使用的现有代码
    + [NSURLConnection sendAsynchronousRequest:queue:completionHandler:]

    NSURLSession创建表示NSURLSessionTask对象代表正在加载资源的操作。这些与之类似NSURLConnection对象,但提供更多的控制和统一委托模型。

    NSURLSessionTask对象始终以挂起状态创建必须在执行之前发送- resume消息。

    NSURLSessionTask的子类用于语法区分数据和文件下载。

    NSURLSessionDataTask以一系列调用的形式接收资源
    URLSession:dataTask:didReceiveData:代理方法。这是一种通常与检索对象关联的任务类型,以便立即解析对象。

    NSURLSessionUploadTaskNSURLSessionDataTask不同在它的实例是如何构建的。上传任务通过引用要上传的文件或数据明确创建对象,或通过利用 - URLSession:task:needNewBodyStream:代理消息提供上传主体。

    NSURLSessionDownloadTask将直接写入响应数据到一个临时文件。完成后,代理发送URLSession:downloadTask:didFinishDownloadingToURL:并给予机会将此文件移动到其沙盒容器中的永久位置,或读取文件。如果取消,NSURLSessionDownloadTask可以产生一个数据blob,可用于稍后恢复下载时间。

    iOS 9Mac OS X 10.11开始,NSURLSessionStream就是可用作的任务类型。这允许直接的TCP / IP连接到一个给定的主机和端口与可选的安全握手和代理的导航。数据任务也可能通过HTTP Upgrade升级到NSURLSessionStream任务:头和适当的使用NSURLSessionConfiguration的流水线选项。请参阅RFC 2817RFC 6455以获取有关Upgrade:header的信息以及关于将数据任务转换为流任务的注释。


    NSURLSession 的优势

    • NSURLSession 支持 http2.0 协议
    • 在处理下载任务的时候可以直接把数据下载到磁盘
    • 支持后台下载/上传
    • 同一个 session 发送多个请求,只需要建立一次连接(复用了TCP)
    • 提供了全局的 session 并且可以统一配置,使用更加方便
    • 下载的时候是多线程异步处理,效率更高

    NSURLSession API

    1. NSURLSession类

    NS_CLASS_AVAILABLE(NSURLSESSION_AVAILABLE, 7_0)
    @interface NSURLSession : NSObject
    
    /*
     * The shared session uses the currently set global NSURLCache,
     * NSHTTPCookieStorage and NSURLCredentialStorage objects.
     */
    @property (class, readonly, strong) 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:(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;
    
    /*
     * The sessionDescription property is available for the developer to
     * provide a descriptive label for the session.
     */
    @property (nullable, copy) NSString *sessionDescription;
    
    /* -finishTasksAndInvalidate returns immediately and existing tasks will be allowed
     * to run to completion.  New tasks may not be created.  The session
     * will continue to make delegate callbacks until URLSession:didBecomeInvalidWithError:
     * has been issued. 
     *
     * -finishTasksAndInvalidate and -invalidateAndCancel do not
     * have any effect on the shared session singleton.
     *
     * When invalidating a background session, it is not safe to create another background
     * session with the same identifier until URLSession:didBecomeInvalidWithError: has
     * been issued.
     */
    - (void)finishTasksAndInvalidate;
    
    /* -invalidateAndCancel acts as -finishTasksAndInvalidate, but issues
     * -cancel to all outstanding tasks for this session.  Note task 
     * cancellation is subject to the state of the task, and some tasks may
     * have already have completed at the time they are sent -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;
    
    @end
    

    下面我们就一起来看一下这些API的用法。

    @property (class, readonly, strong) NSURLSession *sharedSession;
    
    • sharedSession属性表示使用当前的全局的NSURLCache,
      NSHTTPCookieStorageNSURLCredentialStorage对象。
    + (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;
    + (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;
    
    • 这两个方法是用于返回NSURLSession对象的类方法,在创建新会话期间会自定义NSURLSession。如果您只需要使用具有自定义配置选项的便利例程,则无需指定代理。 如果您确实指定代理,那么代理将保留直到代理发送URLSession:didBecomeInvalidWithError:消息。
    @property (readonly, retain) NSOperationQueue *delegateQueue;
    @property (nullable, readonly, retain) id <NSURLSessionDelegate> delegate;
    @property (readonly, copy) NSURLSessionConfiguration *configuration;
    
    • 这里,delegateQueue表示操作队列,delegate表示遵循NSURLSessionDelegate协议的代理,configuration表示配置,用于session实例化的配置。
    @property (nullable, copy) NSString *sessionDescription;
    
    • 可以提供对session 的标签描述。
    - (void)finishTasksAndInvalidate;
    
    • -finishTasksAndInvalidate立即返回,现有任务将被允许运行完成。 新任务可能无法创建。 会话将继续进行代理的回调,直到发布URLSession:didBecomeInvalidWithError:为止。- finishTasksAndInvalidate- invalidateAndCancel对共享会话单例没有任何影响。 当使后台会话无效时,在URLSession:didBecomeInvalidWithError:已经发布之前,使用相同的标识符创建另一个后台会话是不安全的。
    - (void)invalidateAndCancel;
    
    • - invalidateAndCancel充当- finishTasksAndInvalidate,但是会针对此会话的所有未完成任务执行取消- cancel。 注意取消任务取决于任务的状态,某些任务可能在发送-cancel时已经完成。
    - (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. */
    // 清空所有的cookie、cache和凭证,移除磁盘文件,发送- flushWithCompletionHandler:消息,
    // 如果代理队列不为空的话,就在代理队列中调用completionHandler()方法。
    
    - (void)flushWithCompletionHandler:(void (^)(void))completionHandler;    
    /* flush storage to disk and clear transient network caches.  Invokes completionHandler() on the delegate queue if not nil. */
    // 将存储清空到磁盘并清除瞬态网络缓存。 如果不为nil,则在代理队列上调用completionHandler()
    
    - (void)getTasksWithCompletionHandler:(void (^)(NSArray<NSURLSessionDataTask *> *dataTasks, NSArray<NSURLSessionUploadTask *> *uploadTasks, NSArray<NSURLSessionDownloadTask *> *downloadTasks))completionHandler; 
    /* invokes completionHandler with outstanding data, upload and download tasks. */
    // 用数据,上传和下载任务调用completionHandler
    
    - (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. */
    // 用所有未完成的任务调用completionHandler
    

    2. NSURLSession分类NSURLSessionAsynchronousConvenience

    /*
     * NSURLSession convenience routines deliver results to 
     * a completion handler block.  These convenience routines
     * are not available to NSURLSessions that are configured
     * as background sessions.
     *
     * Task objects are always created in a suspended state and 
     * must be sent the -resume message before they will execute.
     */
    // 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
    

    各种形形色色的任务

    下面我们就看一下这些各种不同的任务。

    • @interface NSURLSessionTask : NSObject <NSCopying, NSProgressReporting>
    • @interface NSURLSessionDataTask : NSURLSessionTask
    • @interface NSURLSessionUploadTask : NSURLSessionDataTask
    • @interface NSURLSessionDownloadTask : NSURLSessionTask

    这几个任务类的继承关系如下。

    NSURLSessionTask 是一个抽象类,如果要使用那么只能使用它的子类,NSURLSessionTask 有两个子类。

    • NSURLSessionDataTask,可以用来处理一般的网络请求,如 GET | POST 请求等。NSURLSessionDataTask 有一个子类为 NSURLSessionUploadTask,用于处理上传请求的时候有优势。
    • NSURLSessionDownloadTask,主要用于处理下载请求,有很大的优势。

    各种形形色色的代理

    我们看一下各种不同的代理。

    • @protocol NSURLSessionDelegate <NSObject>
    • @protocol NSURLSessionTaskDelegate <NSURLSessionDelegate>
    • @protocol NSURLSessionDataDelegate <NSURLSessionTaskDelegate>
    • @protocol NSURLSessionDownloadDelegate <NSURLSessionTaskDelegate>
    • @protocol NSURLSessionStreamDelegate <NSURLSessionTaskDelegate>

    大家可以很清楚看到其中的继承关系。

    后记

    本篇主要介绍了NSURLSession的各种API接口,以及几个任务类和代理的继承关系。

    相关文章

      网友评论

      本文标题:详细解析几个和网络请求有关的类 (一) —— NSURLSess

      本文链接:https://www.haomeiwen.com/subject/cigqfftx.html