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

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

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

    版本记录

    版本号 时间
    V1.0 2018.03.08

    前言

    我们做APP发起网络请求,一般都是使用框架,这些框架的底层也都是苹果的API,接下来几篇就一起来看一下和网络有关的几个类。感兴趣的可以看上面几篇文章。
    1. 详细解析几个和网络请求有关的类 (一) —— NSURLSession

    回顾

    上一篇主要介绍了网络请求中最重要的类NSURLSession,并对其中的各种任何和协议进行了分析。这一篇主要讲述请求Request方面的内容。主要从两个类NSURLRequest及其子类NSMutableURLRequest出发,并进行了详细分析。


    NSURLRequest

    1. NSURLRequest本类

    NSURLRequest本类接口如下所示,部分已增加说明和注释。

    @interface NSURLRequest : NSObject <NSSecureCoding, NSCopying, NSMutableCopying>
    {
        @private
        NSURLRequestInternal *_internal;
    }
    
    /*! 
        @method requestWithURL:
        @abstract Allocates and initializes an NSURLRequest with the given
        URL.
        @discussion Default values are used for cache policy
        (NSURLRequestUseProtocolCachePolicy) and timeout interval (60
        seconds).
        // 缓存策略的默认值是NSURLRequestUseProtocolCachePolicy,timeout值为60s
    
        @param URL The URL for the request.
        @result A newly-created and autoreleased NSURLRequest instance.
    */
    + (instancetype)requestWithURL:(NSURL *)URL;
    
    /*!
        @property supportsSecureCoding
        @abstract Indicates that NSURLRequest implements the NSSecureCoding protocol.
        // 表明NSURLRequest实现了NSSecureCoding协议
    
        @result A BOOL value set to YES.
    */
    @property (class, readonly) BOOL supportsSecureCoding;
    
    /*!
        @method requestWithURL:cachePolicy:timeoutInterval:
        @abstract Allocates and initializes a NSURLRequest with the given
        URL and cache policy.
        @param URL The URL for the request. 
        @param cachePolicy The cache policy for the request. 
        @param timeoutInterval The timeout interval for the request. See the
        commentary for the <tt>timeoutInterval</tt> for more information on
        timeout intervals.
        @result A newly-created and autoreleased NSURLRequest instance. 
    */
    + (instancetype)requestWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval;
    
    /*! 
        @method initWithURL:
        @abstract Initializes an NSURLRequest with the given URL. 
        @discussion Default values are used for cache policy
        (NSURLRequestUseProtocolCachePolicy) and timeout interval (60
        seconds).
        @param URL The URL for the request. 
        @result An initialized NSURLRequest. 
    */
    - (instancetype)initWithURL:(NSURL *)URL;
    
    /*! 
        @method initWithURL:
        @abstract Initializes an NSURLRequest with the given URL and
        cache policy.
        @discussion This is the designated initializer for the 
        NSURLRequest class.
        @param URL The URL for the request. 
        @param cachePolicy The cache policy for the request. 
        @param timeoutInterval The timeout interval for the request. See the
        commentary for the <tt>timeoutInterval</tt> for more information on
        timeout intervals.
        @result An initialized NSURLRequest. 
    */
    - (instancetype)initWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval NS_DESIGNATED_INITIALIZER;
    
    /*! 
        @abstract Returns the URL of the receiver. 
        @result The URL of the receiver. 
    */
    @property (nullable, readonly, copy) NSURL *URL;
    
    /*! 
        @abstract Returns the cache policy of the receiver.
        @result The cache policy of the receiver. 
    */
    @property (readonly) NSURLRequestCachePolicy cachePolicy;
    
    /*! 
        @abstract Returns the timeout interval of the receiver.
        @discussion The timeout interval specifies the limit on the idle
        interval alloted to a request in the process of loading. The "idle
        interval" is defined as the period of time that has passed since the
        last instance of load activity occurred for a request that is in the
        process of loading. Hence, when an instance of load activity occurs
        (e.g. bytes are received from the network for a request), the idle
        interval for a request is reset to 0. If the idle interval ever
        becomes greater than or equal to the timeout interval, the request
        is considered to have timed out. This timeout interval is measured
        in seconds.
        @result The timeout interval of the receiver. 
    */
    // timeout 超时时间间隔指定在加载过程中分配给请求的idle interval的限制。 
    “idle interval”定义为自加载过程中发生的加载活动的最后一次实例以来经过的时间段。 
    因此,当发生负载活动的实例发生时(例如,从网络接收到请求的字节数),
    请求的空闲时间间隔将重置为0。如果空闲时间间隔变得大于或等于超时时间间隔,
    则请求被认为已超时。 该超时间隔以秒为单位进行测量。
    @property (readonly) NSTimeInterval timeoutInterval;
    
    /*!
        @abstract The main document URL associated with this load.
        @discussion This URL is used for the cookie "same domain as main
        document" policy. There may also be other future uses.
        See setMainDocumentURL:
        NOTE: In the current implementation, this value is unused by the
        framework. A fully functional version of this method will be available 
        in the future. 
        @result The main document URL.
    */
    // 与此次加载关联的主文档URL。此URL用于“same domain as main
    document”策略的cookie。 也可能有其他未来的用途。 
    请参阅setMainDocumentURL:注意:在当前实现中,该值未被框架使用。 
    该方法的全功能版本将在未来可用。
    @property (nullable, readonly, copy) NSURL *mainDocumentURL;
    
    /*!
     @abstract Returns the NSURLRequestNetworkServiceType associated with this request.
     @discussion  This will return NSURLNetworkServiceTypeDefault for requests that have
     not explicitly set a networkServiceType (using the setNetworkServiceType method).
     @result The NSURLRequestNetworkServiceType associated with this request.
     */
    @property (readonly) NSURLRequestNetworkServiceType networkServiceType API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0));
    
    /*!
     @abstract returns whether a connection created with this request is allowed to use
     the built in cellular radios (if present).
     @result YES if the receiver is allowed to use the built in cellular radios to
     satify the request, NO otherwise.
     */
    // 是否允许使用蜂窝网络
    
    @property (readonly) BOOL allowsCellularAccess  API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0));
    
    @end
    

    下面还有几点需要说明。

    • 缓存策略
    @property (readonly) NSURLRequestCachePolicy cachePolicy;
    
    typedef NS_ENUM(NSUInteger, NSURLRequestCachePolicy)
    {
        NSURLRequestUseProtocolCachePolicy = 0,
    
        NSURLRequestReloadIgnoringLocalCacheData = 1,
        NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, // Unimplemented
        NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData,
    
        NSURLRequestReturnCacheDataElseLoad = 2,
        NSURLRequestReturnCacheDataDontLoad = 3,
    
        NSURLRequestReloadRevalidatingCacheData = 5, // Unimplemented
    };
    
    • 网络服务类型NSURLRequestNetworkServiceType
    /*!
     @enum NSURLRequestNetworkServiceType
     
     @discussion The NSURLRequestNetworkServiceType enum defines constants that
     can be used to specify the service type to associate with this request.  The
     service type is used to provide the networking layers a hint of the purpose 
     of the request.
    // NSURLRequestNetworkServiceType枚举定义了可用于指定与此请求关联的服务类型的常量。 
    服务类型用于向网络层提供请求目的的暗示。
     
     @constant NSURLNetworkServiceTypeDefault Is the default value for an NSURLRequest
     when created.  This value should be left unchanged for the vast majority of requests.
    // NSURLNetworkServiceTypeDefault是NSURLRequest创建时的默认值。
    绝大多数请求的这个值应该保持不变。
     
     @constant NSURLNetworkServiceTypeVoIP Specifies that the request is for voice over IP
     control traffic.
    // NSURLNetworkServiceTypeVoIP指定该请求用于IP语音控制流量
     
     @constant NSURLNetworkServiceTypeVideo Specifies that the request is for video
     traffic.
    // NSURLNetworkServiceTypeVideo指定该请求用于视频流量。
    
     @constant NSURLNetworkServiceTypeBackground Specifies that the request is for background
     traffic (such as a file download).
    // NSURLNetworkServiceTypeBackground指定该请求用于后台流量(如文件下载)
    
     @constant NSURLNetworkServiceTypeVoice Specifies that the request is for voice data.
    // NSURLNetworkServiceTypeVoice指定请求用于语音数据
    
     @constant NSURLNetworkServiceTypeCallSignaling Specifies that the request is for call signaling.
    // NSURLNetworkServiceTypeCallSignaling指定该请求用于呼叫信号
    
    */
    typedef NS_ENUM(NSUInteger, NSURLRequestNetworkServiceType)
    {
        NSURLNetworkServiceTypeDefault = 0, // Standard internet traffic
        NSURLNetworkServiceTypeVoIP = 1,    // Voice over IP control traffic
        NSURLNetworkServiceTypeVideo = 2,   // Video traffic
        NSURLNetworkServiceTypeBackground = 3, // Background traffic
        NSURLNetworkServiceTypeVoice = 4,      // Voice data
        NSURLNetworkServiceTypeCallSignaling API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) = 11, // Call Signaling
    };
    

    2. NSURLRequest分类NSHTTPURLRequest

    /*!
        @category NSURLRequest(NSHTTPURLRequest) 
        The NSHTTPURLRequest on NSURLRequest provides methods for accessing
        information specific to HTTP protocol requests.
    */
    // NSHTTPURLRequest提供了获取指定HTTP协议请求的信息。
    @interface NSURLRequest (NSHTTPURLRequest) 
    
    /*!
        @abstract Returns the HTTP request method of the receiver. 
        @result the HTTP request method of the receiver. 
    */
    // 请求的方式,其实就是GET/POST等
    @property (nullable, readonly, copy) NSString *HTTPMethod;
    
    /*!
        @abstract Returns a dictionary containing all the HTTP header fields
        of the receiver.
        @result a dictionary containing all the HTTP header fields of the
        receiver.
    */
    // 返回一个包含所有HTTP header的字典
    @property (nullable, readonly, copy) NSDictionary<NSString *, NSString *> *allHTTPHeaderFields;
    
    /*! 
        @method valueForHTTPHeaderField:
        @abstract Returns the value which corresponds to the given header
        field. Note that, in keeping with the HTTP RFC, HTTP header field
        names are case-insensitive.
        @param field the header field name to use for the lookup
        (case-insensitive).
        @result the value associated with the given header field, or nil if
        there is no value associated with the given header field.
    */
    // 返回给定的header field相对的值,注意为了遵循HTTP RFC,HTTP header field的名字是区分大小写的。 
    - (nullable NSString *)valueForHTTPHeaderField:(NSString *)field;
    
    /*!
        @abstract Returns the request body data of the receiver. 
        @discussion This data is sent as the message body of the request, as
        in done in an HTTP POST request.
        @result The request body data of the receiver. 
    */
    // 返回请求体的数据,一般是在POST中请求的。
    @property (nullable, readonly, copy) NSData *HTTPBody;
    
    /*!
        @abstract Returns the request body stream of the receiver
        if any has been set
        @discussion The stream is returned for examination only; it is
        not safe for the caller to manipulate the stream in any way.  Also
        note that the HTTPBodyStream and HTTPBody are mutually exclusive - only
        one can be set on a given request.  Also note that the body stream is
        preserved across copies, but is LOST when the request is coded via the 
        NSCoding protocol
        @result The request body stream of the receiver.
    */
    // 返回接收器的请求体流(如果已设置)。该流只返回用于检验,
    调用者以任何方式操纵流是不安全的。 另请注意,HTTPBodyStream
    和HTTPBody是相互排斥的 - 只有一个可以在给定请求上设置。 
    还要注意,body流在副本中保留,但在通过NSCoding协议编码请求时丢失。
    @property (nullable, readonly, retain) NSInputStream *HTTPBodyStream;
    
    /*!
        @abstract Determine whether default cookie handling will happen for 
        this request.
        @discussion NOTE: This value is not used prior to 10.3
        @result YES if cookies will be sent with and set for this request; 
        otherwise NO.
    */
    // 决定是否在此次请求中处理默认cookie,这个值在10.3之前是不可以用的。
    @property (readonly) BOOL HTTPShouldHandleCookies;
    
    /*!
     @abstract Reports whether the receiver is not expected to wait for the
     previous response before transmitting.
     @result YES if the receiver should transmit before the previous response
     is received.  NO if the receiver should wait for the previous response
     before transmitting.
     */
    // 决定是否在上一次请求响应回来之前进行传输新的请求
    @property (readonly) BOOL HTTPShouldUsePipelining API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0));
    
    @end
    

    NSURLRequest类仅用于封装有关URL请求的信息。 您必须使用其他类(如NSURLSessionNSURLConnection)将这些请求发送到服务器。 有关更多信息,请阅读 URL Session Programming Guide

    NSURLRequest被设计为通过添加为您自己的协议特定属性提供访问方法的类别来扩展以支持其他协议。 这些方法可以通过调用NSURLProtocol方法 propertyForKey:inRequest:setProperty:forKey:inRequest:来获取和设置实际值。

    Swift覆盖到Foundation框架提供了URLRequest结构,该结构桥接到NSURLRequest类及其可变子类NSMutableURLRequest。 有关值类型的更多信息,请参阅Using Swift with Cocoa and Objective-C (Swift 4.0.1)中的Working with Cocoa Frameworks


    NSMutableURLRequest

    1. NSMutableURLRequest本类

    @interface NSMutableURLRequest : NSURLRequest
    
    /*! 
        @abstract The URL of the receiver.
    */
    @property (nullable, copy) NSURL *URL;
    
    /*! 
        @abstract The cache policy of the receiver.
    */
    @property NSURLRequestCachePolicy cachePolicy;
    
    /*! 
        @abstract Sets the timeout interval of the receiver.
        @discussion The timeout interval specifies the limit on the idle
        interval allotted to a request in the process of loading. The "idle
        interval" is defined as the period of time that has passed since the
        last instance of load activity occurred for a request that is in the
        process of loading. Hence, when an instance of load activity occurs
        (e.g. bytes are received from the network for a request), the idle
        interval for a request is reset to 0. If the idle interval ever
        becomes greater than or equal to the timeout interval, the request
        is considered to have timed out. This timeout interval is measured
        in seconds.
    */
    @property NSTimeInterval timeoutInterval;
    
    /*!
        @abstract Sets the main document URL
        @discussion The caller should pass the URL for an appropriate main
        document, if known. For example, when loading a web page, the URL
        of the main html document for the top-level frame should be
        passed.  This main document will be used to implement the cookie
        "only from same domain as main document" policy, and possibly
        other things in the future.
        NOTE: In the current implementation, the passed-in value is unused by the
        framework. A fully functional version of this method will be available 
        in the future. 
    */
    @property (nullable, copy) NSURL *mainDocumentURL;
    
    /*!
     @abstract Sets the NSURLRequestNetworkServiceType to associate with this request
     @discussion This method is used to provide the network layers with a hint as to the purpose
     of the request.  Most clients should not need to use this method.
     */
    @property NSURLRequestNetworkServiceType networkServiceType API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0));
    
    /*!
     @abstract sets whether a connection created with this request is allowed to use
     the built in cellular radios (if present). 
     @discussion NO if the receiver should not be allowed to use the built in
     cellular radios to satisfy the request, YES otherwise.  The default is YES.
     */
    @property BOOL allowsCellularAccess API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0));
    
    @end
    

    接口就这么多内容,和NSURLRequest是类似的,具体可参考那个,这里就不多添加注释了。

    2. NSMutableURLRequest分类NSMutableHTTPURLRequest

    /*!
        @category NSMutableURLRequest(NSMutableHTTPURLRequest) 
        The NSMutableHTTPURLRequest on NSMutableURLRequest provides methods
        for configuring information specific to HTTP protocol requests.
    */
    @interface NSMutableURLRequest (NSMutableHTTPURLRequest) 
    
    /*!
        @abstract Sets the HTTP request method of the receiver. 
    */
    @property (copy) NSString *HTTPMethod;
    
    /*!
        @abstract Sets the HTTP header fields of the receiver to the given
        dictionary.
        @discussion This method replaces all header fields that may have
        existed before this method call. 
        <p>Since HTTP header fields must be string values, each object and
        key in the dictionary passed to this method must answer YES when
        sent an <tt>-isKindOfClass:[NSString class]</tt> message. If either
        the key or value for a key-value pair answers NO when sent this
        message, the key-value pair is skipped.
    */
    @property (nullable, copy) NSDictionary<NSString *, NSString *> *allHTTPHeaderFields;
    
    /*! 
        @method setValue:forHTTPHeaderField:
        @abstract Sets the value of the given HTTP header field.
        @discussion If a value was previously set for the given header
        field, that value is replaced with the given value. Note that, in
        keeping with the HTTP RFC, HTTP header field names are
        case-insensitive.
        @param value the header field value. 
        @param field the header field name (case-insensitive). 
    */
    - (void)setValue:(nullable NSString *)value forHTTPHeaderField:(NSString *)field;
    
    /*! 
        @method addValue:forHTTPHeaderField:
        @abstract Adds an HTTP header field in the current header
        dictionary.
        @discussion This method provides a way to add values to header
        fields incrementally. If a value was previously set for the given
        header field, the given value is appended to the previously-existing
        value. The appropriate field delimiter, a comma in the case of HTTP,
        is added by the implementation, and should not be added to the given
        value by the caller. Note that, in keeping with the HTTP RFC, HTTP
        header field names are case-insensitive.
        @param value the header field value. 
        @param field the header field name (case-insensitive). 
    */
    - (void)addValue:(NSString *)value forHTTPHeaderField:(NSString *)field;
    
    /*!
        @abstract Sets the request body data of the receiver.
        @discussion This data is sent as the message body of the request, as
        in done in an HTTP POST request.
    */
    @property (nullable, copy) NSData *HTTPBody;
    
    /*!
        @abstract Sets the request body to be the contents of the given stream. 
        @discussion The provided stream should be unopened; the request will take
        over the stream's delegate.  The entire stream's contents will be 
        transmitted as the HTTP body of the request.  Note that the body stream
        and the body data (set by setHTTPBody:, above) are mutually exclusive 
        - setting one will clear the other.
    */
    @property (nullable, retain) NSInputStream *HTTPBodyStream;
    
    /*!
        @abstract Decide whether default cookie handling will happen for 
        this request (YES if cookies should be sent with and set for this request;
        otherwise NO).
        @discussion The default is YES - in other words, cookies are sent from and 
        stored to the cookie manager by default.
        NOTE: In releases prior to 10.3, this value is ignored
    */
    @property BOOL HTTPShouldHandleCookies;
    
    /*!
     @abstract Sets whether the request should not wait for the previous response 
     before transmitting (YES if the receiver should transmit before the previous response is
     received.  NO to wait for the previous response before transmitting)
     @discussion Calling this method with a YES value does not guarantee HTTP 
     pipelining behavior.  This method may have no effect if an HTTP proxy is
     configured, or if the HTTP request uses an unsafe request method (e.g., POST
     requests will not pipeline).  Pipelining behavior also may not begin until
     the second request on a given TCP connection.  There may be other situations
     where pipelining does not occur even though YES was set.
     HTTP 1.1 allows the client to send multiple requests to the server without
     waiting for a response.  Though HTTP 1.1 requires support for pipelining,
     some servers report themselves as being HTTP 1.1 but do not support
     pipelining (disconnecting, sending resources misordered, omitting part of
     a resource, etc.).
     */
    @property BOOL HTTPShouldUsePipelining API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0));
    
    @end
    

    大家发现这个和NSURLRequest分类NSHTTPURLRequest也是类似的,那么也就不多添加注释了,具体大家可以参考上面所做的注释。

    NSURLSessionNSURLConnectionNSURLDownload类为传递给它们的初始化器和task创建方法的每个NSMutableURLRequest对象进行了深拷贝。

    URL加载系统旨在为您处理HTTP协议的各个方面。 因此,不应使用addValue:forHTTPHeaderField:或者 setValue:forHTTPHeaderField:修改以下headers。

    • Authorization
    • Connection
    • Host
    • Proxy-Authenticate
    • Proxy-Authorization
    • WWW-Authenticate

    后记

    本篇主要介绍了NSURLRequestNSMutableURLRequest的本类和分类的接口使用文档。

    相关文章

      网友评论

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

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