Objective-C的网络请求-任务处理相关学习笔记

NSURLSessionConfiguration - URL会话配置

定义URL会话的行为和策略的配置对象。NSURLSessionConfiguration对象定义使用NSURLSession对象上传和下载数据时要使用的行为和策略。上传或下载数据时,创建NSURLSessionConfiguration对象始终是必须采取的第一步。可以使用此对象来配置超时值、缓存策略、连接要求以及要与NSURLSession对象一起使用的其他类型的信息。

在使用NSURLSessionConfiguration对象初始化NSURLSession对象之前,必须对其进行适当配置。NSURLSession对象复制提供的配置设置,并使用这些设置配置到会话中。配置后,NSURLSession对象将忽略对NSURLSessionConfiguration对象所做的任何更改。如果需要修改传输策略,则必须更新NSURLSessionConfiguration对象并使用它创建新的NSURLSession对象。

在某些情况下,此配置中定义的策略可能会被为任务提供的NSURLRequest对象指定的策略覆盖。除非会话的策略更具限制性,例如如果会话配置指定不允许蜂窝网络,则NSURLRequest对象无法请求蜂窝网络。否则将遵守NSURLRequest对象上指定的任何策略。

NSURLSessionConfiguration常用属性
@property (class, readonly, strong) NSURLSessionConfiguration *defaultSessionConfiguration;

属性描述类属性,默认会话配置对象。默认会话配置使用基于磁盘的持久缓存(结果下载到文件时除外),并将凭据存储在用户的密钥链中。它还将cookie(默认情况下)存储在与NSURLConnection和NSURLDownload类相同的共享cookie存储中。修改返回的会话配置对象不会影响将来调用此方法返回的任何配置对象,也不会更改现有会话的默认行为。因此,使用返回的对象作为额外定制的起点总是安全的。

@property (class, readonly, strong) NSURLSessionConfiguration *ephemeralSessionConfiguration;

属性描述类属性,临时会话配置对象。临时会话配置对象类似于默认会话配置,只是对应的会话对象不将缓存、凭据存储或任何与会话相关的数据存储到磁盘上。相反,与会话相关的数据存储在RAM中。临时会话将数据写入磁盘的唯一时间是当您告诉它将URL的内容写入文件时。

@property (nullable, readonly, copy) NSString *identifier;

属性描述配置对象的后台会话标识符。此属性的值仅在使用backgroundSessionConfigurationWithIdentifier:方法创建配置对象时设置。字符串唯一标识一个后台会话对象。在iOS中,可以在应用程序后台传输终止的情况下使用这个字符串。当应用程序重新启动时,它使用该字符串重新创建与传输相关的配置和会话对象。

@property NSURLRequestCachePolicy requestCachePolicy;

属性描述一个预定义的常量,用于确定何时从缓存中返回响应。配置对象根据此属性确定会话内任务使用的请求缓存策略。此属性的值为NSURLRequestCachePolicy中定义的常量之一,以指定缓存策略是否应依赖于过期日期和有效期,缓存是否应完全禁用,以及是否应联系服务器以确定自上次请求以来内容是否已更改。默认值为NSURLRequestUseProtocolCachePolicy。

@property NSTimeInterval timeoutIntervalForRequest;

属性描述配置对象根据此属性确定会话内所有任务的请求超时间隔,默认值为60。请求超时间隔控制任务在放弃之前等待额外数据到达的时间(以秒为单位)。每当有新数据到达时,与此值关联的计时器将被重置。当请求计时器到达指定的时间间隔而没有收到任何新数据时,它将触发超时。

任何由后台会话创建的上传或下载任务,如果原始请求由于超时而失败,将自动重试。若要配置上传或下载任务允许重试超时时间,则使用timeoutIntervalForResource属性。

@property NSTimeInterval timeoutIntervalForResource;

属性描述允许资源请求所花费的最大时间,默认值为7天。配置对象根据此属性确定会话内所有任务的资源超时间隔。资源超时间隔控制在放弃之前等待整个资源传输的时间(以秒为单位)。资源计时器在请求启动时开始计数,直到请求完成或达到该超时间隔(以先到者为准)。

@property NSURLRequestNetworkServiceType networkServiceType;

属性描述配置对象使用此属性设置会话中所有任务的网络服务类型。默认值为NSURLNetworkServiceTypeDefault。此设置还会影响Wi-Fi服务质量(QoS)优先级。网络服务类型向操作系统提供关于底层流量用于做什么的提示。此提示增强了系统对流量进行优先级排序、确定唤醒蜂窝或Wi-Fi无线电所需的速度等的能力。通过提供准确的信息,可以提高系统在电池寿命、性能和其他考虑因素之间进行最佳平衡的能力。

例如,如果您的应用程序正在执行用户未请求的下载(如预取内容),则指定NSURLNetworkServiceTypeBackground类型,以便在用户选择查看时可用。

  • NSURLRequestNetworkServiceType提供的枚举值:
typedef NS_ENUM(NSUInteger, NSURLRequestNetworkServiceType)
{
    //标准互联网流量
    NSURLNetworkServiceTypeDefault = 0,
    //IP语音控制流量
    NSURLNetworkServiceTypeVoIP API_DEPRECATED("Use PushKit for VoIP control purposes", macos(10.7,10.15), ios(4.0,13.0), watchos(2.0,6.0), tvos(9.0,13.0)) = 1,    
    //视频流量
    NSURLNetworkServiceTypeVideo = 2,   
    //后台流量
    NSURLNetworkServiceTypeBackground = 3, 
    //语音数据
    NSURLNetworkServiceTypeVoice = 4,      
    //响应性数据
    NSURLNetworkServiceTypeResponsiveData = 6, 
    //多媒体音频/视频流
    NSURLNetworkServiceTypeAVStreaming API_AVAILABLE(macosx(10.9), ios(7.0), watchos(2.0), tvos(9.0)) = 8 , 
    //响应式多媒体音频/视频
    NSURLNetworkServiceTypeResponsiveAV API_AVAILABLE(macosx(10.9), ios(7.0), watchos(2.0), tvos(9.0)) = 9,
    //呼叫信令
    NSURLNetworkServiceTypeCallSignaling API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) = 11, 
};
@property BOOL allowsCellularAccess;

属性描述一个布尔值,用于确定是否应通过蜂窝网络进行连接。默认值为YES。此属性控制基于此会话配置的会话中的任务是否允许通过蜂窝网络进行连接。

@property BOOL allowsExpensiveNetworkAccess API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0));

属性描述一个布尔值,指示连接是否可以使用系统认为昂贵的网络接口。系统根据网络接口的性质和其他因素来决定什么是“昂贵”。iOS 13认为大多数蜂窝网络和个人热点都很昂贵。如果没有可用的非昂贵网络接口,并且会话的allowsExpensiveNetworkAccess属性为NO,则从会话创建的任何任务都会失败。在这种情况下,当任务失败时提供的错误具有networkUnavailableReason属性,其值为NSURLErrorNetworkUnavailableReasonExpensive。

可以限制应用程序使用昂贵的网络访问用户发起的任务,并推迟可自由支配的任务,直到一个不昂贵的接口可用。为此,设置allowsExpensiveNetworkAccess (和 allowsConstrainedNetworkAccess) 为NO,waitsForConnectivity为YES。这样,NSURLSessionTask在发送或接收数据之前等待一个合适的接口变得可用。

要测试此属性的行为,您可以在设备中选择设置>开发人员>网络,覆盖设备的蜂窝和Wi-Fi成本的当前值。

建议你的应用程序的策略逻辑围绕allowsConstrainedNetworkAccess属性,而不是这个。使用应用程序的用户可以使用“低数据模式”设置来设置受限状态,从而选择使用可能是昂贵的网络。

@property BOOL allowsConstrainedNetworkAccess API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0));

属性描述一个布尔值,指示当用户指定低数据模式时连接是否可以使用网络。在iOS 13及更高版本中,用户可以将他们的设备设置为使用低数据模式作为设置应用程序中的蜂窝数据选项之一。用户可以打开低数据模式来减少应用程序的网络数据使用量。当用户打开低数据模式时,此属性控制URL会话的行为。如果没有可用的非受限网络接口,并且会话的allowsConstrainedNetworkAccess属性为NO,则从会话创建的任何任务都会失败。在这种情况下,当任务失败时提供的错误具有networkUnavailableReason属性,其值为NSURLErrorNetworkUnavailableReasonConstrained。

限制应用程序使用受限网络访问用户发起的任务,并推迟可自由支配的任务,直到一个非受限接口可用。为此,设置allowsConstrainedNetworkAccess (和 allowsExpensiveNetworkAccess)为YES。这样,NSURLSessionTask在发送或接收数据之前等待一个合适的接口变得可用。

@property BOOL requiresDNSSECValidation API_AVAILABLE(macos(13.0), ios(16.0), watchos(9.0), tvos(16.0));

属性描述要求在启用DNSSEC验证的情况下发出会话请求。默认为NO。

@property BOOL waitsForConnectivity API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

属性描述一个布尔值,指示会话是否应该等待连接变得可用,还是立即失败。由于某些原因,连接可能暂时不可用。例如当allowsCellularAccess设置为false时,设备可能只有蜂窝连接,或者设备可能需要VPN连接,但没有可用的VPN连接。如果这个属性的值为true并且没有足够的连接,会话调用NSURLSessionTaskDelegate的URLSession:taskIsWaitingForConnectivity: 方法并等待连接。当连接性可用时,任务开始其工作,并最终像往常一样调用代理或完成处理程序。如果该属性的值为false且连接不可用,则连接将立即失败,并出现错误,例如NSURLErrorNotConnectedToInternet错误。

此属性仅在建立连接期间相关。如果连接建立后又断开,完成处理程序或委托会接收一个错误,例如NSURLErrorNetworkConnectionLost错误。

后台会话将忽略此属性,后台会话始终等待连接。

@property (getter=isDiscretionary) BOOL discretionary API_AVAILABLE(macos(10.10), ios(7.0), watchos(2.0), tvos(9.0));

属性描述一个布尔值,它决定是否可以根据系统的判断来调度后台任务以获得最佳性能。对于使用backgroundSessionConfigurationWithIdentifier:方法创建的配置对象,使用此属性让系统控制何时应该发生传输。使用其他方法创建的配置对象将忽略此属性。

当传输大量数据时,建议将此属性的值设置为YES。这样做可以让系统在对设备更优的时间安排这些传输。例如,系统可能会延迟传输大文件,直到设备插入并通过Wi-Fi连接到网络。该属性的默认值为NO。

会话对象仅将此属性的值应用于应用程序在前台启动时的传输。对于在应用程序处于后台时启动的传输,系统总是根据自己的判断启动传输——换句话说,系统假设此属性为YES并忽略您指定的任何值。

@property (nullable, copy) NSString *sharedContainerIdentifier API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));

属性描述共享容器的标识符,后台URL会话中的文件应该下载到其中。创建一个URL会话供应用程序扩展使用,请将此属性设置为应用程序扩展及其包含应用程序之间共享的容器的有效标识符。如果尝试从应用程序扩展创建URL会话,但未能将此属性设置为有效值,则URL会话将在创建时无效。

@property BOOL sessionSendsLaunchEvents API_AVAILABLE(macos(11.0), ios(7.0), watchos(2.0), tvos(9.0));

属性描述一个布尔值,指示传输完成时应用程序是否应在后台启动或唤醒。对于使用backgroundSessionConfigurationWithIdentifier:方法创建的配置对象,可以使用此属性来控制iOS应用程序的启动行为。对于使用其他方法创建的配置对象,此属性将被忽略。该属性的默认值为YES。当该属性值为YES时,当会话任务完成或需要身份验证时,系统会自动在后台唤醒或启动iOS应用程序。这时,系统调用应用程序代理的application:handleEventsForBackgroundURLSession:completionHandler: 方法,为它提供需要注意的会话标识符。如果应用程序必须重新启动,可以使用该标识符创建一个新的配置和会话对象,该对象能够为任务提供服务。

@property tls_protocol_version_t TLSMinimumSupportedProtocolVersion API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0));

属性描述:客户端在此会话中进行连接时应接受的最低TLS协议版本。

@property tls_protocol_version_t TLSMaximumSupportedProtocolVersion API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0));

属性描述:客户端在此会话中进行连接时应请求的最高TLS协议版本。

@property BOOL HTTPShouldUsePipelining;

属性描述一个布尔值,用于确定会话是否应使用HTTP通道。此属性确定基于此配置的会话中的任务是否应使用HTTP通道。

@property BOOL HTTPShouldSetCookies;

属性描述一个布尔值,用于确定请求是否应包含来自Cookie存储区的Cookie。此属性控制基于此配置的会话中的任务在发出请求时是否应自动提供来自共享Cookie存储区的Cookie。如果需要自己提供Cookie,将此值设置为NO,并通过会话的HTTPAdditionalHeaders属性或使用自定义NSURLRequest对象在每个请求级别上提供Cookie报头。此属性默认值为YES。

@property NSHTTPCookieAcceptPolicy HTTPCookieAcceptPolicy;

属性描述一个策略常数,用于确定何时应该接受Cookie的策略。此属性控制基于此配置的会话中的所有任务的Cookie接受策略。默认值为NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain。如果想更直接地控制哪些Cookie被接受,设置这个值为NSHTTPCookieAcceptPolicyNever,然后使用allHeaderFields属性和cookiesWithResponseHeaderFields:forURL: 方法自己从URL响应对象中提取Cookie。

@property (nullable, copy) NSDictionary *HTTPAdditionalHeaders;

属性描述与请求一起发送的附加头的字典。此属性控制基于此配置的会话中的所有任务的附加头。例如可以设置User-Agent头,这样它就会自动包含在应用程序通过基于此配置的会话发出的每个请求中。

NSURLSession对象旨在为您处理HTTP协议的各个方面。因此,您不应修改以下标头:

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

此外,如果可以自动确定上传正文数据的长度,例如如果为正文内容提供NSData对象,则会设置Content-Length的值。

如果在这个字典和请求对象(如果适用)中都出现了相同的头,则请求对象的值优先。默认值为空字典。

@property (nullable, retain) NSHTTPCookieStorage *HTTPCookieStorage;

属性描述Cookie存储,用于存储此会话中的Cookie。此属性控制基于此配置的会话中的所有任务使用的Cookie存储对象。要禁用Cookie存储,请将此属性设置为nil。

对于默认会话和后台会话,默认值为sharedHTTPCookieStorage的cookie存储对象。对于临时会话,默认值是一个私有cookie存储对象,仅在内存中存储数据,并在会话无效时销毁。

@property (nullable, retain) NSURLCredentialStorage *URLCredentialStorage;

属性描述为身份验证提供凭据的凭据存储。此属性控制基于此配置的会话中的所有任务使用的凭据存储对象。如果不想使用凭据存储,请将此属性设置为nil。

对于默认会话和后台会话,默认值是sharedCredentialStorage凭据存储对象。对于临时会话,默认值是一个私有凭据存储对象,仅在内存中存储数据,并且在使会话无效时销毁该值。

@property (nullable, retain) NSURLCache *URLCache;

属性描述URL缓存,用于为会话中的请求提供缓存响应。此属性控制基于此配置的会话中的任务使用的URL缓存对象。要禁用缓存,请将此属性设置为nil。

对于默认会话,默认值为sharedURLCache对象。对于后台会话,默认值为nil。对于临时会话,默认值是仅在内存中存储数据的私有缓存对象,并且在使会话无效时销毁该值。

@property BOOL shouldUseExtendedBackgroundIdleMode API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0));

属性描述一个布尔值,指示当应用程序移动到后台时,TCP连接是否应保持打开。除了请求连接保持打开之外,将这个值设置为YES会要求系统在应用程序移动到后台时延迟回收连接。

@property (nullable, copy) NSArray<Class> *protocolClasses;

属性描述在会话中处理请求的一组额外的协议子类,默认值为空数组。。这个数组中的对象是Class对象,对应于你定义的自定义NSURLProtocol子类。URL会话对象默认支持许多常见的网络协议。此数组可包含自定义的一个或多个协议,用于扩展会话使用的通用网络协议的默认集。在处理请求之前,NSURLSession对象首先搜索默认协议,然后检查自定义协议,直到找到一个能够处理指定请求的协议。 它使用canInitWithRequest: 类方法返回值为YES的协议,表示该类能够处理指定的请求。不能将自定义NSURLProtocol子类与后台会话一起使用。

@property NSURLSessionMultipathServiceType multipathServiceType API_AVAILABLE(ios(11.0)) API_UNAVAILABLE(macos, watchos, tvos);

属性描述一种服务类型,用于指定通过Wi-Fi和蜂窝接口传输数据的多路径TCP连接策略。多路径TCP,由RFC 6824中的IETF定义,是TCP的扩展,允许多个接口传输单个数据流。该功能允许从Wi-Fi到蜂窝网络的无缝切换,旨在提高两种界面的效率,并改善用户体验。

multipathServiceType属性定义了多路径TCP堆栈使用哪个策略来调度跨Wi-Fi和蜂窝接口的流量。默认值为none,即关闭多路径TCP。还可以选择切换模式,实现Wi-Fi和蜂窝网络的无缝切换。多路径TCP需要服务器支持。

+ (NSURLSessionConfiguration *)backgroundSessionConfigurationWithIdentifier:(NSString *)identifier API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));

函数描述创建允许在后台执行HTTP和HTTPS上传或下载的会话配置对象。当应用程序在后台运行时,使用此方法初始化一个适合传输数据文件的配置对象。配置了此对象的会话将传输的控制权移交给系统,系统在单独的进程中处理传输。在iOS中,这种配置使得即使应用本身被暂停或终止,传输也可以继续进行。

如果一个iOS应用程序被系统终止并重新启动,该应用程序可以使用相同的标识符创建一个新的配置对象和会话,并检索在终止时正在进行的传输状态。此行为仅适用于系统正常终止应用程序。如果用户在多任务屏幕上终止了应用程序,系统会取消所有会话的后台传输。此外,系统不会自动重新启动被用户强制退出的应用程序。用户必须显式地重新启动应用程序才能再次开始传输。

可以使用discretionary属性配置后台会话,当传输大量数据时,建议将此属性的值设置为YES。

参数 :

identifier :配置对象的唯一标识符。此参数不能为nil或空字符串。

返回值 :一个配置对象,它使系统在单独的进程中执行上传和下载任务。

NSURLSession - URL会话(协调一组相关网络数据传输任务)

NSURLSession派生自NSObject,是用来协调一组相关网络数据传输任务的对象。NSURLSession类和相关类提供的API支持从URL指示的端点下载数据并将数据上传到该端点,支持执行后台下载,支持身份验证,支持允许应用程序收到重定向等事件的通知。

使用NSURLSession的API,可以为应用程序创建一个或多个会话,每个会话协调一组相关的数据传输任务,每个任务表示对特定URL的请求

通过NSURLSession对象创建的任务,需要调用resume方法启动任务

NSURLSession常用属性
@property (class, readonly, strong) NSURLSession *sharedSession;

属性描述类属性,返回共享的具有默认行为的单例会话对象。共享会话只需通过直接使用此属性来访问它,不需要提供代理或配置对象。

@property (readonly, retain) NSOperationQueue *delegateQueue;

属性描述创建会话对象时提供的操作队列。此队列必须在对象创建时设置且不能更改。与会话相关的所有代理方法调用和完成处理程序都在此队列上执行。会话对象保持对此队列的强引用,如果会话对象最终没有被释放,则会泄漏内存。

@property (nullable, readonly, retain) id <NSURLSessionDelegate> delegate;

属性描述创建此对象时指定的代理。此代理对象必须在对象创建时设置且不能更改。此代理对象负责处理身份验证、做出缓存决策以及处理其他与会话相关的事件。会话对象保持对该代理的强引用,如果会话对象最终没有被释放,则会泄漏内存。

@property (readonly, copy) NSURLSessionConfiguration *configuration;

属性描述只读属性,为此会话定义行为和策略的配置对象的副本。对于从NSURLSession对象返回的该配置进行任何进一步更改都不会影响该会话的行为,但是可以使用修改后的配置对象创建一个新的会话。

@property (nullable, copy) NSString *sessionDescription;

属性描述应用程序为会话定义的描述性标签,默认为nil。此属性包含可用于调试目的的可读字符串。

NSURLSession常用函数
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;

函数描述使用指定的会话配置创建会话

参数 :

configuration :一个指定某些行为的配置对象。

返回值 :使用指定的会话配置初始化的NSURLSession对象。

+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration delegate:(nullable id <NSURLSessionDelegate>)delegate delegateQueue:(nullable NSOperationQueue *)queue;

函数描述使用指定的会话配置、代理和操作队列创建会话。使用此方法创建NSURLSession对象,如果代理不为nil,需要释放NSURLSession对象,否则应用程序可能泄漏内存;代理如果为nil,则该类只能与接受完成处理程序的方法一起使用。

参数 :

configuration :一个指定某些行为的配置对象。

delegate :处理身份验证请求和其他与会话相关的事件的会话代理对象。

queue :用于调度代理调用和完成处理程序的操作队列。队列应该是串行队列,以确保回调的正确顺序。如果为nil,会话将创建一个串行操作队列来执行所有代理方法调用和完成处理程序调用。

返回值 :使用指定的会话配置、代理和操作队列初始化的NSURLSession对象。

- (void)finishTasksAndInvalidate;

函数描述使会话失效,但允许任何未完成的任务完成。此方法立即返回,而不等待任务完成。一旦会话失效,就不能在会话中创建新任务,但现有任务将继续执行,直到完成。在最后一个任务完成后,会话进行与这些任务相关的最后一个代理的调用,会话调用其代理上的URLSession:didBecomeInvalidWithError: 方法,然后中断对代理和回调对象的引用。失效后,会话对象不能被重用。对sharedSession方法返回的会话调用此方法无效

- (void)invalidateAndCancel;

函数描述取消所有未完成的任务,然后使会话失效。一旦失效,对委托和回调对象的引用就会中断。失效后,会话对象不能被重用。对sharedSession方法返回的会话调用此方法无效

- (void)resetWithCompletionHandler:(void (NS_SWIFT_SENDABLE ^)(void))completionHandler; 

函数描述:清空所有cookie,缓存和凭证存储,删除磁盘文件,并隐式调用flushWithCompletionHandler:方法,在委托队列上调用完成处理程序。

参数 :

completionHandler :完成处理程序。

- (void)flushWithCompletionHandler:(void (NS_SWIFT_SENDABLE ^)(void))completionHandler;  

函数描述:将存储刷新到磁盘并清除临时网络缓存。

参数 :

completionHandler :完成处理程序。

- (void)getTasksWithCompletionHandler:(void (NS_SWIFT_SENDABLE ^)(NSArray<NSURLSessionDataTask *> *dataTasks, NSArray<NSURLSessionUploadTask *> *uploadTasks, NSArray<NSURLSessionDownloadTask *> *downloadTasks))completionHandler;

函数描述:在完成处理程序中获取未完成的数据任务、上传任务和下载任务。

参数 :

completionHandler :完成处理程序。传递给完成处理程序的数组包含在会话中创建的任何任务,但不包括已完成、已失败或被取消后无效的任何任务。

- (void)getAllTasksWithCompletionHandler:(void (NS_SWIFT_SENDABLE ^)(NSArray<__kindof NSURLSessionTask *> *tasks))completionHandler;

函数描述:异步调用一个会话中所有任务的完成回调,可以在完成处理程序中获取所有的未完成任务。

参数 :

completionHandler :完成处理程序,其中接收一个任务列表参数。

- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request;

函数描述创建基于指定URL请求对象检索URL内容的任务。通过基于请求对象创建任务,可以通过请求对象调整任务行为的各个方面,包括缓存策略和超时间隔。

参数 :

request :URL请求对象,提供请求特定信息,如URL、缓存策略、请求类型和正文数据或正文流。

返回值 :新的会话数据任务。

- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url;

函数描述创建检索指定URL内容的任务。该任务调用会话代理上的方法,提供响应元数据、响应数据等。

参数 :

url :要检索的URL。

返回值 :新的会话数据任务。

- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL;

函数描述创建一个基于指定URL请求对象的执行HTTP请求用于上传指定文件的任务。请求对象为上传提供元数据(如HTTP请求头)。该任务调用会话代理上的方法来提供上传进度、响应元数据、响应数据等。HTTP上传请求是任何包含请求体的请求,例如POST或PUT请求

参数 :

request :URL请求对象,提供URL、缓存策略、请求类型等。此请求对象中的正文流和正文数据将被忽略。

fileURL :要上传的文件的URL。

返回值 :新的会话上传任务。

- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(NSData *)bodyData;

函数描述创建一个基于指定URL请求对象的执行HTTP请求用于上传指定数据的任务。该任务调用会话代理上的方法来提供上传进度、响应元数据、响应数据等。

参数 :

request :URL请求对象,提供URL、缓存策略、请求类型等。此请求对象中的正文流和正文数据将被忽略。

bodyData :上传的主体数据。

返回值 :新的会话上传任务。

- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request;

函数描述创建一个基于指定URL请求对象的执行HTTP请求的上传任务。该任务调用会话代理上的方法来提供上传进度、响应元数据、响应数据等。会话的代理必须实现URLSession:task:needNewBodyStream:方法,来为该方法提供要上传的主体数据

参数 :

request :URL请求对象,提供URL、缓存策略、请求类型等。此请求对象中的正文流和正文数据将被忽略。

- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request;

函数描述创建一个下载任务,该任务根据指定的URL请求对象检索URL的内容,并将结果保存到文件中。该任务调用会话代理上的方法,以提供进度通知、生成的临时文件的位置等。通过基于请求对象创建任务,可以调整任务行为的各个方面,包括缓存策略和超时间隔。

参数 :

request :一个URL请求对象,提供URL、缓存策略、请求类型、主体数据或主体流等。

返回值 :新的会话下载任务。

- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url;

函数描述创建一个下载任务,检索指定URL的内容并将结果保存到文件中。该任务调用会话代理上的方法,以提供进度通知、生成的临时文件的位置等。

参数 :

url :要下载内容的URL。

返回值 :新的会话下载任务。

- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData;

函数描述创建下载任务以恢复以前取消或失败的下载。这个方法等价于downloadTaskWithResumeData:completionHandler:并为完成处理程序传递一个nil参数。

参数 :

resumeData :一个数据对象,提供恢复下载所需的数据。

返回值 :新的会话下载任务。

- (NSURLSessionStreamTask *)streamTaskWithHostName:(NSString *)hostname port:(NSInteger)port API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0));

函数描述创建一个任务,该任务建立到指定主机名和端口的双向TCP/IP连接

参数 :

hostname :连接端点的主机名。

port :连接端点的端口。

返回值 :新的会话流任务。

- (NSURLSessionWebSocketTask *)webSocketTaskWithURL:(NSURL *)url API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0));

函数描述为提供的URL创建WebSocket任务。所提供的URL必须具有ws或wss方案。

参数 :

url :要创建WebSocket连接的URL。

返回值 :新的会话WebSocket任务。

- (NSURLSessionWebSocketTask *)webSocketTaskWithURL:(NSURL *)url protocols:(NSArray<NSString *>*)protocols API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0));

函数描述在给定URL和协议数组的情况下创建WebSocket任务。在WebSocket握手期间,任务使用提供的协议与服务器协商首选协议。该协议不会影响WebSocket框架。

参数 :

url :要创建WebSocket连接的URL。

protocols :与服务器协商的一系列协议。

返回值 :新的会话WebSocket任务。

- (NSURLSessionWebSocketTask *)webSocketTaskWithRequest:(NSURLRequest *)request API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0));

函数描述为提供的URL请求创建WebSocket任务。可以在对任务调用resume方法之前修改请求的属性。任务在HTTP握手阶段使用这些属性。要添加自定义协议,请添加一个带有Sec-WebSocket-Protocol密钥的头,以及一个以逗号分隔的协议列表,这些协议是希望与服务器协商的。客户端提供的自定义HTTP头在与服务器握手时保持不变。

参数 :

request :一个URL请求,指示要连接的WebSockets端点。

返回值 :新的会话WebSocket任务。

NSURLSession (NSURLSessionAsynchronousConvenience) - 分类扩展的异步处理会话数据任务的便捷代码块

NSURLSession提供的便捷程序方法创建任务,执行任务后将任务结果交付给完成处理程序块。完成处理程序块在代理队列上执行。如果完成处理程序不为nil,通过使用完成处理程序,该任务将绕过对用于响应和数据传递的代理方法的调用,而是在完成处理程序中提供任何生成的NSData、NSURL、 NSURLResponse和NSError对象。但仍然调用用于处理身份验证的代理方法如果为完成处理程序传递nil,则相当于调用了NSURLSession提供与之对应的不带完成完成处理程序块的任务创建函数,如果设置了代理,则在任务完成时仅调用会话代理方法

  • 这些便捷的程序方法对于配置为后台会话的NSURLSessions是不可用的

  • 任务对象总是在挂起状态下创建,并且在执行之前必须调用resume方法

- (NSURLSessionDataTask *)dataTaskWithURL:(NSURL *)url completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;

函数描述创建检索指定URL数据内容的任务,然后在完成时调用处理程序

参数 :

url : 要检索的URL。

completionHandler : 加载请求完成时调用的完成处理程序。此完成处理程序接受以下参数:

  • data :服务器返回的数据。如果请求失败,则为nil。
  • response :服务器提供响应元数据(如HTTP响应头和状态代码)的对象。接收到响应后,无论请求是否成功完成或失败都包含信息。如果您正在发出HTTP或HTTPS请求,则返回的对象实际上是NSHTTPURLResponse对象。
  • error : 一个错误对象,指示请求失败的原因;如果请求成功,则为nil。

返回值 : 新会话数据任务。

- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request completionHandler:(void (^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;

函数描述创建基于指定的URL请求对象检索URL数据内容的任务,并在完成时调用处理程序。通过基于请求对象创建任务,可以调整任务行为的各个方面,包括缓存策略和超时间隔。

参数 :

request : 提供URL、缓存策略、请求类型、正文数据或正文流等的URL请求对象。

completionHandler : 加载请求完成时要调用的完成处理程序。此完成处理程序接受以下参数:

  • data :服务器返回的数据。
  • response :服务器提供响应元数据(如HTTP响应头和状态代码)的对象。
  • error :指示请求失败原因的错误对象,如果请求成功则为nil。

返回值 : 新的会话数据任务。

\color{red}{例如通过基于请求对象创建请求任务的简单代码片段: }

//初始化Url
NSURL *url = [[NSURL alloc]initWithString:@"请求的url"];
//可变URL加载请求
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url];
//设置请求方式(默认也是GET)
[request setHTTPMethod:@"GET"];
//设置请求头
request.allHTTPHeaderFields = @{@"Content-Type":@"application/x-www-form-urlencoded",@"User-Agent":@"szyapp/ios"};
//通过单例初始化网络数据传输任务对象
NSURLSession *session = [NSURLSession sharedSession];
//通过基于请求对象创建请求任务
[[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
  if(error == nil){
      //请求成功
      //将响应数据转换为字典
      NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
      NSLog(@"%@",jsonDict);
   }else{
      NSLog(@"%@",error);
   }
}]resume];

注:NSLocalizedDescription=The resource could not be loaded because the App Transport Security policy requires the use of a secure connection(译:NSLocalizedDescription=无法加载资源,因为应用传输安全策略要求使用安全连接)错误可能是需要发送https请求,结果发送http请求导致的

- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromFile:(NSURL *)fileURL completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;

函数描述创建一个任务,执行用于上传指定文件的HTTP请求,然后在完成时调用处理程序。此方法返回的响应体是接收到的完整响应体。HTTP上传请求是任何包含请求体的请求,例如POST或PUT请求。上传任务要求创建一个请求对象,以便为上传提供元数据,如HTTP请求头。

如果不需要响应数据,则可以为completionHandler传递nil,可以使用键值观察来观察任务状态的变化,以确定任务何时完成。

参数 :

request :提供URL、缓存策略、请求类型等的NSURLRequest实例。此请求对象中的正文流和正文数据将被忽略。

fileURL :要上传的文件的URL。

completionHandler :上传请求完成时调用的完成处理程序。此完成处理程序接受以下参数:

  • data :服务器返回的数据。如果请求失败,则为nil。
  • response :服务器提供响应元数据(如HTTP响应头和状态代码)的对象。
  • error :一个错误对象,指示请求失败的原因,如果请求成功则为nil。

返回值 :会话新创建的上传任务。

- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request fromData:(nullable NSData *)bodyData completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;

函数描述创建一个任务,该任务为指定的URL请求对象执行HTTP请求,上传提供的数据(NSData),并在完成时调用处理程序。此方法返回的响应体是接收到的完整响应体。

如果不需要响应数据,则可以为completionHandler传递nil,可以使用键值观察来观察任务状态的变化,以确定任务何时完成。

参数 :

request :提供URL、缓存策略、请求类型等的NSURLRequest实例。此请求对象中的正文流和正文数据将被忽略。

bodyData :请求的主体数据。

completionHandler :上传请求完成时调用的完成处理程序。此完成处理程序接受以下参数:

  • data :服务器返回的数据。如果请求失败,则为nil。
  • response :服务器提供响应元数据(如HTTP响应头和状态代码)的对象。
  • error :一个错误对象,指示请求失败的原因,如果请求成功则为nil。

返回值 :会话新创建的上传任务。

- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;

函数描述创建一个下载任务,该任务根据指定的URL请求对象检索URL的内容,将结果保存到文件中,并在完成时调用处理程序。通过基于请求对象创建任务,可以优化任务行为的各个方面,包括缓存策略和超时间隔。

参数 :

request :一个URL请求对象,提供URL、缓存策略、请求类型、主体数据或主体流等。

completionHandler :下载请求完成时调用的完成处理程序。此完成处理程序接受以下参数:

  • location :请求成功完成,为存储服务器响应的临时文件的位置。请求失败,则为nil。在完成处理程序返回之前,必须移动该文件或将其打开以供阅读。否则文件将被删除,数据丢失。
  • response :服务器提供响应元数据(如HTTP响应头和状态代码)的对象。
  • error :一个错误对象,指示请求失败的原因,如果请求成功则为nil。

返回值 :会话新创建的下载任务。

- (NSURLSessionDownloadTask *)downloadTaskWithURL:(NSURL *)url completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;

函数描述创建下载任务,检索指定URL的内容,将结果保存到文件中,并在完成时调用处理程序

参数 :

url :提供要下载的URL的NSURL对象。

completionHandler :下载请求完成时调用的完成处理程序。此完成处理程序接受以下参数:

  • location :请求成功完成,为存储服务器响应的临时文件的位置。请求失败,则为nil。在完成处理程序返回之前,必须移动该文件或将其打开以供阅读。否则文件将被删除,数据丢失。
  • response :服务器提供响应元数据(如HTTP响应头和状态代码)的对象。
  • error :一个错误对象,指示请求失败的原因,如果请求成功则为nil。

返回值 :会话新创建的下载任务。

- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error))completionHandler;

函数描述创建一个下载任务以恢复先前取消或失败的下载,并在完成时调用处理程序。应用程序可以通过两种方式获取resumeData对象:

  • 1.如果应用程序通过调用cancelByProducingResumeData:方法,取消了一个现有的传输,会话对象将一个resumeData对象传递给cancelByProducingResumeData:方法提供的完成处理程序。
    1. 如果传输失败,会话对象提供一个NSError对象给它的代理或者任务的完成处理程序。在该对象中,userInfo字典中的NSURLSessionDownloadTaskResumeData键包含一个resumeData对象。

需要注意的是只有请求是HTTP或HTTPS的GET请求时,并且远程服务器支持字节范围请求(带有Range报头)并在其响应中提供ETag或Last-Modified报头时,才能恢复下载。如果服务器上的文件已被修改,或者由于磁盘空间不足而删除了临时文件,下载也可能重新启动。

参数 :

resumeData :一个数据对象,提供恢复下载所需的数据。

completionHandler :下载请求完成时调用的完成处理程序。此完成处理程序接受以下参数:

  • location :请求成功完成,为存储服务器响应的临时文件的位置。请求失败,则为nil。在完成处理程序返回之前,必须移动该文件或将其打开以供阅读。否则文件将被删除,数据丢失。
  • response :服务器提供响应元数据(如HTTP响应头和状态代码)的对象。
  • error :一个错误对象,指示请求失败的原因,如果请求成功则为nil。

返回值 :会话新创建的下载任务。

NSURLSessionDelegate - 处理会话级事件的代理

一种协议,定义URL会话实例调用其代理来处理会话级事件(如会话生命周期更改)的方法。除此协议中定义的方法外,大多数委托还应实现NSURLSessionTaskDelegate、NSURLSessionDataDelegate和NSURLSessionDownloadDelegate协议中的一些或所有方法来处理任务级事件。这些事件包括单个任务的开始和结束,以及数据或下载任务的定期进度更新。

NSURLSessionDelegate代理函数
- (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(nullable NSError *)error;

函数描述通知代理URL会话对象的会话已无效。如果通过调用其finishTasksAndInvalidate方法使会话失效,则会话将一直等待,直到会话中的最后一个任务完成或失败后才调用此代理方法。如果调用invalidateAndCancel方法,会话将立即调用此代理方法。

参数 :

session :无效的会话对象。

error :导致无效的错误,如果是显式的使会话无效,则为nil。

- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
                                             completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler;

函数描述从代理请求凭据,以响应来自远程服务器的会话级身份验证请求。在两种情况下调用此方法:

  • 当远程服务器要求客户端证书或Windows NT LAN Manager (NTLM)身份验证时,允许应用程序提供适当的凭据。
  • 当会话第一次建立到使用SSL或TLS的远程服务器的连接时,允许您的应用程序验证服务器的证书链。

需要注意的是这个方法只处理NSURLAuthenticationMethodNTLM、NSURLAuthenticationMethodNegotiate、NSURLAuthenticationMethodClientCertificate和NSURLAuthenticationMethodServerTrust认证类型。对于所有其他身份验证方案或未实现该方法,会话会调用代理的URLSession:task:didReceiveChallenge:completionHandler: 方法。

参数 :

session :包含需要请求身份验证的任务的会话。

challenge :包含身份验证请求的对象。

completionHandler :代理方法必须调用的处理程序。这个完成处理程序接受以下参数:

  • disposition :描述如何处理验证的几个常量之一。
  • credential :如果disposition设置为NSURLSessionAuthChallengeUseCredential,则该参数为应该用于身份验证的凭据,否则为NULL。
- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session API_AVAILABLE(macos(11.0), ios(7.0), watchos(2.0), tvos(9.0));

函数描述通知代理为后台会话排队的所有消息都已交付。当应用程序稍后接收到URLSessionDidFinishEventsForBackgroundURLSession:消息时,这表明之前为该会话排队的所有消息都已经交付,现在可以安全地调用之前存储的完成处理程序或开始任何可能导致调用完成处理程序的内部更新。

参数 :

session :不再有任何未完成请求的会话。

NSURLSessionTask - 会话任务基类

NSURLSessionTask类是URL会话中任务的基类。任务总是会话的一部分,可以通过调用NSURLSession实例上的一个任务创建方法来创建任务,所调用的方法决定任务的类型。

  • 使用NSURLSession的dataTaskWithURL: 方法和其相关的方法来创建NSURLSessionDataTask实例。数据任务请求一个资源,以内存中的一个或多个NSData对象的形式返回服务器的响应。支持默认会话、临时会话和共享会话,但不支持后台会话。

  • 使用NSURLSession的uploadTaskWithRequest:方法和其相关的方法来创建NSURLSessionUploadTask实例。上传任务与数据任务类似,只是它们更容易提供请求体,以便在检索服务器响应之前上传数据。后台会话支持上传任务。

  • 使用NSURLSession的downloadTaskWithURL: 相关的方法来创建NSURLSessionDownloadTask实例。下载任务将资源直接下载到磁盘上的文件。在任何类型的会话中都支持下载任务。

  • 使用NSURLSession的streamTaskWithHostName:port: 方法或streamTaskWithNetService: 方法来创建NSURLSessionStreamTask实例。流任务从主机名和端口或网络服务对象建立TCP/IP连接。

创建任务后,通过调用resume方法启动任务。然后会话保持对任务的强引用,直到请求完成或失败。你不需要维护对任务的引用,除非它对应用程序的内部记录有用。

所有任务属性都支持键值观察

NSURLSessionTask常用属性
@property (readonly)                 NSUInteger    taskIdentifier;

属性描述给定会话中任务的唯一标识符。该值仅在单个会话的上下文中是唯一的,其他会话中的任务可以具有相同的taskIdentifier值。

@property (nullable, readonly, copy) NSURLRequest  *originalRequest;

属性描述创建任务时传递的原始请求对象。这个值通常与当前活动的请求(currentRequest)相同,除非服务器已经响应了初始请求,并将其重定向到另一个URL。

@property (nullable, readonly, copy) NSURLRequest  *currentRequest;

属性描述任务当前正在处理的URL请求对象。这个值通常与初始请求(originalRequest)相同,除非服务器已经响应了初始请求,并将初始请求重定向到另一个URL。

@property (nullable, readonly, copy) NSURLResponse *response;

属性描述服务器对当前活动请求的响应。该对象提供由服务器提供的关于请求的信息。该信息总是包含原始URL,还可能包括预期长度、MIME类型信息、编码信息、建议文件名或这些的组合。

@property (nullable, retain) id <NSURLSessionTaskDelegate> delegate API_AVAILABLE(macos(12.0), ios(15.0), watchos(8.0), tvos(15.0));

属性描述特定于任务的代理。此特定于任务的代理在会话的代理接收消息之前接收来到自任务的消息。

@property (readonly, strong) NSProgress *progress API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

属性描述表示总体任务进度的对象

@property (nullable, copy) NSDate *earliestBeginDate API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

属性描述网络加载开始的最早日期。对于从后台NSURLSession实例创建的任务,此属性表示网络加载不应早于此日期开始。设置此属性不能保证加载将在指定日期开始,只能保证加载不会更早开始。如果未指定,则不使用启动延迟。此属性对从非后台会话创建的任务无效

@property int64_t countOfBytesClientExpectsToSend API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

属性描述客户端期望发送的字节数的最佳预估上限。为此属性设置的值应考虑HTTP报头和正文数据或正文流的大小。如果不指定,则使用NSURLSessionTransferSizeUnknown。系统使用此属性优化URL会话任务的调度。强烈建议开发人员尽可能提供一个近似的上限,或者一个精确的字节计数,而不是接受默认值。

@property int64_t countOfBytesClientExpectsToReceive API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

属性描述客户端期望接收的字节数的最佳预估上限。为此属性设置的值应考虑HTTP响应标头和响应体的大小。如果不指定,则使用NSURLSessionTransferSizeUnknown。系统使用此属性优化URL会话任务的调度。强烈建议开发人员尽可能提供一个近似的上限,或者一个精确的字节计数,而不是接受默认值。

@property (readonly) int64_t countOfBytesSent;

属性描述任务在请求正文中发送给服务器的字节数。此字节计数仅包括请求体本身的长度,而不包括请求头。要在该值更改时得到通知,需要实现URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:代理方法。

@property (readonly) int64_t countOfBytesReceived;

属性描述任务在响应正文中从服务器接收的字节数。要在该值更改时得到通知,需要实现URLSession:dataTask:didReceiveData: 代理方法(用于数据和上传任务)或URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:方法(用于下载任务)。

@property (readonly) int64_t countOfBytesExpectedToSend;

属性描述任务希望在请求正文中发送的字节数。URL加载系统可以通过三种方式确定上传数据的长度: 1. 作为上传主体提供的数据对象的长度。2. 来自作为上传任务时上传主体提供的磁盘上文件的长度。3. 从请求对象中的Content-Length(如果显式地设置了它)确定。否则,如果您提供了流或主体数据对象,则值为NSURLSessionTransferSizeUnknown (-1),如果没有提供,则为0。

@property (readonly) int64_t countOfBytesExpectedToReceive;

属性描述任务希望在响应正文中接收的字节数。该值基于从服务器接收的Content-Length响应头确定。如果该响应头不存在,则值为NSURLSessionTransferSizeUnknown。

@property (nullable, copy) NSString *taskDescription;

属性描述应用程序为当前任务提供的字符串描述。系统不解释该值,把它用于你认为合适的任何目的。例如可以存储任务的描述以用于调试,或者在自己的数据结构中存储跟踪任务的键。

@property (readonly) NSURLSessionTaskState state;

属性描述任务的当前状态。分为活动、挂起、正在取消或已完成。

  • NSURLSessionTaskState提供的任务当前状态枚举值:
typedef NS_ENUM(NSInteger, NSURLSessionTaskState) {
    //该任务当前正在由会话提供服务(活动)
    NSURLSessionTaskStateRunning = 0, 
    //该任务已被应用程序挂起
    NSURLSessionTaskStateSuspended = 1,
    //该任务已经取消
    NSURLSessionTaskStateCanceling = 2,   
    //任务已完成
    NSURLSessionTaskStateCompleted = 3, 
} API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0));
@property (nullable, readonly, copy) NSError *error;

属性描述指示任务失败原因的错误对象。如果任务仍处于活动状态或传输成功完成,则此值为nil。

@property float priority API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));

属性描述希望主机处理任务的相对优先级,指定为0.0(最低优先级)到1.0(最高优先级)之间的浮点值。为主机提供提示,告诉主机如何从应用程序中将URL会话任务划分优先级,请为每个任务指定优先级。指定优先级只能提供提示,不能保证性能。如果不指定优先级,URL会话任务的优先级为NSURLSessionTaskPriorityDefault,值为0.5。

可以在任何时候指定或更改任务的优先级,但并不是所有的网络协议都在任务启动后响应更改。没有API可以从主机的角度确定任务的有效优先级。

NSURLSessionTask常用函数
- (void)suspend;

函数描述暂时挂起任务。挂起的任务不会产生网络流量,也不受超时的影响。调用resume方法可以恢复数据传输。

- (void)resume;

函数描述如果任务已挂起,则继续执行该任务。新初始化的任务以挂起状态开始,因此需要调用此方法来启动任务。

- (void)cancel;

函数描述取消任务,可以在挂起的任务上调用此方法。此方法立即返回,将任务标记为已取消。一旦一个任务被标记为取消,会调用任务代理对象的URLSession:task:didCompleteWithError: 方法,在域NSURLErrorDomain中传递一个带有代码NSURLErrorCancelled的错误。在某些情况下,任务可以在确认取消之前向其代理发送消息。

NSURLSessionTaskDelegate - 处理任务级事件的代理

一种定义方法的协议,定义了NSURLSession实例在其代理上调用这些方法来处理任务级事件,同时遵循了NSURLSessionDelegate协议。如果使用dataTaskWithURL:和downloadTaskWithURL:等方法将任务添加到会话中,则在会话中设置的代理中实现此协议的方法。该会话代理还可以根据需要实现其他协议,如NSURLSessionDownloadDelegate和NSURLSessionDataDelegate协议。还可以将此类型的代理直接分配给任务,以便在任务将回调传递给会话级的代理之前将回调拦截。

处理事件时,如果提供完成处理程序回调以获取数据的情况下,不需要为NSURLSession对象设置代理,此时使用系统提供的代理。

NSURLSessionTaskDelegate代理函数
- (void)URLSession:(NSURLSession *)session didCreateTask:(NSURLSessionTask *)task
    API_AVAILABLE(macos(13.0), ios(16.0), watchos(9.0), tvos(16.0));

函数描述通知代理任务已经创建。此方法是任务发送的第一条消息,在任务恢复之前提供配置任务的位置。这个代理回调被NOT分派到代理队列。在任务创建方法返回之前以同步方式调用它。

参数 :

session :包含已创建任务的会话。

task :已经创建的任务。

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                        willBeginDelayedRequest:(NSURLRequest *)request
                              completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSURLSessionDelayedRequestDisposition disposition, NSURLRequest * _Nullable newRequest))completionHandler
    API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

函数描述通知代理延迟的URL会话任务现在将开始加载。当一个延迟开始时间的后台会话任务准备开始时(使用earliestBeginDate属性设置)调用此方法。只有当请求在等待网络负载时可能变得过时并且需要被新请求替换时,才应实现此代理方法。为了继续加载,代理必须调用完成处理程序,并传入指示任务应如何进行的设置。传递NSURLSessionDelayedRequestCancel处理相当于直接在任务上调用cancel。

参数 :

session :包含延迟请求的会话。

task :处理延迟请求的任务。

request :被延迟的请求。

completionHandler :执行请求的完成处理程序。完成处理程序接受两个参数:一个是指示任务如何继续的处置方式,另一个是仅在处置为NSURLSessionDelayedRequestUseNewRequest时才使用的新请求对象。

- (void)URLSession:(NSURLSession *)session taskIsWaitingForConnectivity:(NSURLSessionTask *)task
    API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));

函数描述通知代理在开始网络加载之前,任务正在等待合适的连接可用。如果NSURLSessionConfiguration的waitsForConnectivity属性为true,并且连接不足,则调用此方法。代理可以利用此机会更新用户界面,例如通过呈现离线模式或仅蜂窝模式。每个任务最多调用一次此方法,并且仅在连接最初不可用时调用。后台会话不会调用它,因为这些会话会忽略waitsForConnectivity属性。

参数 :

session :包含等待任务的会话。

task :等待连接变化的任务。

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                     willPerformHTTPRedirection:(NSHTTPURLResponse *)response
                                     newRequest:(NSURLRequest *)request
                              completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSURLRequest * _Nullable))completionHandler;

函数描述通知代理远程服务器要求HTTP重定向。仅对默认会话和临时会话中的任务调用此方法,后台会话中的任务自动遵循重定向。

参数 :

session :包含其请求导致重定向的任务的会话。

task :其请求导致重定向的任务。

response :包含服务器对原始请求的响应的对象。

request :用新的请求位置填充的NSURLRequest对象。

completionHandler :处理程序应该使用请求参数的值、修改后的NSURLRequest对象或NULL来调用该块,以拒绝重定向并返回重定向响应的主体。

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                            didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge 
                              completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler;

函数描述向代理请求凭据,以响应来自远程服务器的身份验证请求。此方法处理任务级别的身份验证请求,对于非会话级别的验证(所有其他),NSURLSession对象调用会话代理的该方法来处理身份验证请求。如果应用提供了一个会话代理,并且需要处理身份验证,那么必须在任务级别处理身份验证,或者提供一个任务级别的处理程序,显式地调用每个会话的处理程序。

参数 :

session :包含请求需要身份验证的任务的会话。

task :请求需要身份验证的任务。

challenge :包含身份验证请求的对象。

completionHandler :委托方法必须调用的处理程序。其中参数disposition指示如何处理身份验证验证的几个常量之一;参数credential如果配置为NSURLSessionAuthChallengeUseCredential,则应用于身份验证的凭据,否则为NULL。

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                              needNewBodyStream:(void (NS_SWIFT_SENDABLE ^)(NSInputStream * _Nullable bodyStream))completionHandler NS_SWIFT_ASYNC_NAME(urlSession(_:needNewBodyStreamForTask:));

函数描述当任务需要新的请求正文流发送到远程服务器时,通知代理。任务在两种情况下调用此委托方法:

  • 如果使用uploadTaskWithStreamedRequest创建任务,则提供初始请求体流。
  • 如果由于身份验证质询或其他可恢复服务器错误,任务需要重新发送具有正文流的请求,则提供替换请求正文流。

如果代码使用文件URL或NSData对象提供请求主体,则不需要实现此方法。

参数 :

session :包含需要新正文流的任务的会话。

task :需要新正文流的任务。

completionHandler :一个完成处理程序,代理方法应该用新的正文流调用它。

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                                didSendBodyData:(int64_t)bytesSent
                                 totalBytesSent:(int64_t)totalBytesSent
                       totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend;

函数描述定期通知代理向服务器发送正文内容的进度。totalBytesSent和totalBytesExpectedToSend参数也可以作为NSURLSessionTask的countOfBytesSent和countOfBytesExpectedToSend属性的值。或者由于NSURLSessionTask支持NSProgressReporting,也可以使用任务的进度属性,这可能更方便。

参数 :

session :包含数据任务的会话。

task :数据任务。

bytesSent :自上次调用此委托方法以来发送的字节数。

totalBytesSent :到目前为止发送的字节总数。

totalBytesExpectedToSend :主体数据的预期长度。URL加载系统可以通过三种方式确定上传数据的长度: 1. 从作为上传体提供的NSData对象的长度;2. 来自作为上传任务时上传主体提供的磁盘上文件的长度;3. 从请求对象中的Content-Length(如果显式地设置了它)开始。否则,如果提供了流或主体数据对象,则值为NSURLSessionTransferSizeUnknown(-1),如果没有提供,则为0。

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));

函数描述收集完任务的完整统计信息后调用。如果实现这个代理方法,就可以通过该回调的NSURLSessionTaskMetrics 类型参数获取到采集的网络指标,实现对网络请求中DNS的查询、TCP的建立连接、TLS 握手、请求响应等各环节时间的统计。

参数 :

session :收集监控指标的会话。

task :已收集指标的任务。

metrics :收集的指标。

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
                           didCompleteWithError:(nullable NSError *)error;

函数描述通知代理任务已完成数据传输。代理通过error参数接收的唯一错误是描述客户端发生的错误,如果要检查服务器端错误,则检查此回调接收到的task参数的响应属性。

参数 :

session :已完成数据传输任务的数据任务会话。

task :已完成数据传输的任务。

error :如果发生错误,则表示传输失败的错误对象,否则为NULL。

NSURLSessionDataTask - URL会话数据任务

一个URL会话任务,它直接将下载的数据返回到内存中的应用程序。NSURLSessionDataTask是NSURLSessionTask的一个具体子类。NSURLSessionDataTask类中的方法被记录在NSURLSessionTask中

数据任务将数据作为一个或多个NSData对象直接返回给在内存中的应用程序。当使用数据任务时可以:

  • 在上传主体数据期间(如果应用程序提供任何数据),会话定期调用其代理的URLSession:task:didSendBodyData: totalbytesessent:totalBytesExpectedToSend:方法报告向服务器发送正文内容的进度。

  • 在接收到初始响应后,会话调用它的委托的URLSession:dataTask:didReceiveResponse:completionHandler:方法,可以检查状态代码和响应头,并可选地将数据任务转换为下载任务。

  • 在传输过程中,会话调用它的委托的URLSession:dataTask:didReceiveData:方法,通知代理数据任务已收到一些预期数据。

  • 任务完成接收所有预期数据后,会话调用它的代理的URLSession:dataTask:willCacheResponse:completionHandler:方法,决定是否应该缓存响应。

NSURLSessionUploadTask - URL会话上传任务

在请求体中将数据上传到网络的URL会话任务。NSURLSessionUploadTask类是NSURLSessionDataTask的子类,而NSURLSessionDataTask又是NSURLSessionTask的具体子类。与NSURLSessionUploadTask类相关的方法被记录在NSURLSessionTask中

上传任务用于发出需要请求体(如POST或PUT)的HTTP请求。它们的行为与数据任务类似,但是通过在会话类上调用不同的方法来创建它们,这些方法旨在更容易地提供要上传的内容。与数据任务一样,如果服务器提供了响应,上传任务将该响应作为内存中的一个或多个NSData对象返回。

与数据任务不同,可以使用上传任务在后台上传内容。

创建上传任务时,提供一个NSURLRequest实例,该实例可能包含需要与上传的数据一起发送的任何附加请求头,例如内容类型、内容处置等。在iOS中,当你在后台会话中为一个文件创建上传任务时,系统会将该文件复制到一个临时位置,并从那里传输数据。

在上传过程中,任务会定期调用会话代理的URLSession:(NSURLSession *)session task: didSendBodyData: totalBytesSent: totalBytesExpectedToSend:方法来提供状态信息。

当请求的上传阶段结束时,该任务的行为类似于数据任务,调用会话代理上的方法提供服务器的响应标头、状态码、内容数据等。

NSURLSessionDataDelegate - 处理数据和上传任务的协议

一种定义方法的协议,定义了NSURLSession实例调用其代理来处理数据和上传任务特有的任务级事件的方法,同时遵循了NSURLSessionTaskDelegate协议。使用时需要为NSURLSessionDelegate分配代理对象,如果不分配代理,NSURLSession将使用系统提供的代理。如果NSURLSession创建任务时使用了dataTaskWithRequest: completionHandler:等带有完成处理程序的方法创建任务,则会调用完成处理程序块的方法,而不会调用用于响应和数据传递的代理方法。

NSURLSessionDataDelegate代理函数
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
                                 didReceiveResponse:(NSURLResponse *)response
                                  completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSURLSessionResponseDisposition disposition))completionHandler;

函数描述通知代理数据任务收到了来自服务器的初始应答(响应头)。实现此方法是可选的,除非在需要在第一次接收到响应头时取消传输或将其转换为下载任务。如果不提供此代理方法,则NSURLSession始终允许任务继续。

如果需要支持相当模糊的multipart/x-mix -replace(具有多个部分的内容的MIME(互联网媒体类型)类型,每个部分都替换了前一部分)内容类型,也可以实现此方法。使用该内容类型,服务器发送一系列数据部件,数据每一个部分都用于替换前一个部分。会话在每个部分的开头调用这个方法,然后用该部分的内容调用一个或多个URLSession:dataTask:didReceiveData:方法。每次URLSession:dataTask: didreceiverresponse:completionHandler:方法被一个部分调用时,收集为前一个部分接收的数据(如果有的话),并根据应用程序的需要处理数据。这种处理可以包括将数据存储到文件系统、将其解析为自定义类型或将其显示给用户。接下来,通过使用NSURLSessionResponseAllow常量调用完成处理程序来开始接收下一部分。最后,如果还实现了URLSession:task:didCompleteWithError:方法,NSURLSession将在发送完最后一部分的所有数据后调用它。

参数 :

session :收到初始应答的数据任务会话。

dataTask :接收到初始应答的数据任务。

response :用响应头填充的Url响应对象。

completionHandler :一个完成处理程序,代码调用它来传递一个NSURLSessionResponseDisposition常量用以指示传输应该作为数据任务继续还是应该成为下载任务。

  • NSURLSessionResponseDisposition提供的枚举值:
typedef NS_ENUM(NSInteger, NSURLSessionResponseDisposition) {
    //任务将被取消
    NSURLSessionResponseCancel = 0,
    //该任务将继续作为数据任务                                      
    NSURLSessionResponseAllow = 1,
    //转为下载任务,代理的URLSession:dataTask:didBecomeDownloadTask:方法会被调用,用来提供一个新的下载任务来取代当前的任务。                                     
    NSURLSessionResponseBecomeDownload = 2,       
    //将任务转换为流任务,代理的URLSession:dataTask:didBecomeStreamTask:方法会被调用,用来提供一个新的流任务。来取代当前的任务。                       
    NSURLSessionResponseBecomeStream API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)) = 3, 
} API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0));
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
                              didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask;

函数描述通知代理数据任务已更改为下载任务。当在URLSession: dataTask: didReceiveResponse: completionHandler: 代理方法中使用NSURLSessionResponseBecomeDownload来处置将请求数据转换为使用下载时,会话调用这个代理方法提供新的下载任务。在此调用之后,会话的代理将不再接收与原始数据任务相关的其他代理方法的调用。

参数 :

session : 包含被下载任务替换的任务的会话。

dataTask :被下载任务替换的数据任务。

downloadTask :替换数据任务的新下载任务。

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
                                didBecomeStreamTask:(NSURLSessionStreamTask *)streamTask
    API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0));

函数描述通知代理数据任务已更改为流任务。当URLSession:dataTask:didReceiveResponse:completionHandler:代理方法使用NSURLSessionResponseBecomeStream来处置将请求数据转换为使用流任务时,会话调用此代理方法提供新的流任务。在该调用之后,会话的代理将不再接收与原始数据任务相关的代理方法的调用。

对于流式的请求,流任务只允许读取,会立即发送消通知代理对象的URLSession:writeClosedForStreamTask:方法。通过在其NSURLSessionConfiguration对象上设置HTTPShouldUsePipelining属性,可以禁用会话中的所有流式请求,或者通过在NSURLRequest对象上设置HTTPShouldUsePipelining属性来禁用单个流式请求。

参数 :

session :包含被流任务替换的任务的会话。

dataTask :被流任务替换的数据任务。

streamTask :替换数据任务的新流任务。

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask 
                                     didReceiveData:(NSData *)data;

函数描述通知代理数据任务已经接收到一些预期的数据。此代理方法可以被调用多次,并且每次调用只提供自前一次调用以来收到的数据。如果需要这些数据,应用程序来负责积累这些数据。

因为data参数通常是由许多不同的数据对象拼凑在一起的,所以只要可能,就应使用enumerateByteRangesUsingBlock:方法来遍历数据,而不是使用bytes方法(将数据对象压扁为单个内存块)。

参数 :

session :接收到一些预期数据的数据任务会话。

dataTask :接收到一些预期数据的数据任务。

data :包含着接收到的一些预期数据的数据对象。

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
                                  willCacheResponse:(NSCachedURLResponse *)proposedResponse 
                                  completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSCachedURLResponse * _Nullable cachedResponse))completionHandler;

函数描述询问代理数据(或上传)任务是否应将响应存储在缓存中。任务完成接收所有预期数据后,会话调用此代理方法。如果不实现此方法,默认行为是使用会话配置对象中指定的缓存策略。此方法的主要目的是防止缓存特定URL或修改与URL响应关联的userInfo字典。

只有当处理请求的NSURLProtocol决定缓存响应时,才会调用此方法。作为规则,只有当以下所有条件都为真时,响应才会被缓存:

  • 请求是HTTP或HTTPS URL(或您自己的支持缓存的自定义网络协议)。
  • 请求成功(状态代码在200–299范围内)。
  • 所提供的响应来自服务器,而不是缓存。
  • 会话配置的缓存策略允许缓存。
  • 所提供的URLRequest对象的缓存策略(如果适用)允许缓存。
  • 服务器响应中与缓存相关的头(如果存在)允许缓存。
  • 响应大小足够小,可以合理地容纳在缓存中(例如,如果您提供磁盘缓存,响应必须不大于磁盘缓存大小的5%左右)。

参数 :

session :包含数据(或上传)任务的会话。

dataTask :数据(或上传)任务。

proposedResponse :默认的缓存行为。这种行为是基于当前缓存策略和接收到的标头的值决定的,比如Pragma和Cache-Control头。

completionHandler :处理程序必须调用的块,提供原始建议响应、该响应的修改版本或NULL以防止缓存响应。如果代理实现此方法,则必须调用此完成处理程序,否则应用程序会泄漏内存。

NSURLSessionDownloadTask - URL会话下载任务

将下载的数据存储到文件中的URL会话任务。NSURLSessionDownloadTask是NSURLSessionTask的一个具体子类,NSURLSessionTask提供了NSURLSessionDownloadTask类的大部分方法

下载任务直接将服务器的响应数据写入临时文件,当数据从服务器到达时,可以为应用程序提供进度更新。当在后台会话中使用下载任务时,即使应用处于挂起状态或没有运行,这些下载也会继续。

可以暂停(取消)下载任务并稍后恢复它们(假设服务器支持这样做)。还可以恢复由于网络连接问题而失败的下载。

- (void)cancelByProducingResumeData:(void (NS_SWIFT_SENDABLE ^)(NSData * _Nullable resumeData))completionHandler;

函数描述取消下载,会调用超类中cancel函数。如果条件允许在未来恢复下载,则为完成处理程序提供resumeData对象。它可以与downloadTaskWithResumeData:方法结合使用,以尝试恢复下载。

参数 :

completionHandler :成功取消下载后调用的完成处理程序。如果下载是可恢复的,则为完成处理程序提供resumeData对象。应用程序可以稍后将此对象传递给会话的如果下载是可恢复的,则为完成处理程序提供resumeData对象。您的应用程序可以稍后将此对象传递给会话的downloadTaskWithResumeData: 方法或downloadTaskWithResumeData:completionHandler: 方法来创建一个新任务,在任务停止的地方继续下载。此块不能保证在特定线程上下文中执行。因此可能需要指定一个适当的调度队列,以便在其中执行任何工作。

NSURLSessionDownloadDelegate - 处理下载任务的协议

一种协议,它定义了NSURLSession实例在其代理上调用的方法,以处理特定于下载任务的任务级事件。同时遵循了NSURLSessionTaskDelegate协议。除此协议中的方法外,还需确保实现NSURLSessionTaskDelegate和NSURLSessionDelegate协议中的方法来分别处理所有任务类型和会话级别事件的公共事件。

使用时需要为NSURLSessionDelegate分配代理对象,如果不分配代理,NSURLSession将使用系统提供的代理。如果NSURLSession创建任务时使用了downloadTaskWithRequest: completionHandler:等带有完成处理程序的方法创建任务,则会调用完成处理程序块的方法,而不会调用用于响应和数据传递的代理方法。

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
                              didFinishDownloadingToURL:(NSURL *)location;

函数描述通知代理下载任务已完成下载

参数 :

session :包含已完成的下载任务的会话。

downloadTask :已经完成的下载任务。

location :临时文件的文件URL。因为这个文件是临时的,所以在从这个代理方法返回之前,要么必须打开文件进行读取,要么将其移动到应用程序沙箱容器目录中的永久位置。如果选择打开文件进行读取,则应该在另一个线程中进行实际读取,以避免阻塞代理队列。

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
                                           didWriteData:(int64_t)bytesWritten
                                      totalBytesWritten:(int64_t)totalBytesWritten
                              totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite;

函数描述定期通知代理下载进度

参数 :

session :包含下载任务的会话。

downloadTask :下载任务。

bytesWritten :自上次调用此代理方法以来传输的字节数。

totalBytesWritten :到目前为止传输的字节总数。

totalBytesExpectedToWrite :文件的预期长度,由Content-Length头提供,如果没有提供该响应头,则值为NSURLSessionTransferSizeUnknown。

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
                                      didResumeAtOffset:(int64_t)fileOffset
                                     expectedTotalBytes:(int64_t)expectedTotalBytes;

函数描述通知代理下载任务已恢复下载。如果可恢复的下载任务被取消或失败,可以请求一个resumeData对象,该对象提供足够的信息以便将来重新启动下载。之后可以调用downloadTaskWithResumeData:或downloadTaskWithResumeData:completionHandler: 方法并传递resumeData对象恢复下载,此时将得到一个新的下载任务,会话就会使用该新任务调用此方法,以指示下载已恢复。

参数 :

session :包含已恢复的下载任务的会话。

downloadTask :恢复下载的任务。

fileOffset :如果文件的缓存策略或上次修改日期阻止重用现有内容,则该值为0。否则,该值是一个整数,表示磁盘上不需要再次检索的字节数。(在某些情况下,在文件中恢复传输的时间可能早于上一次传输结束的时间。)

expectedTotalBytes :文件的预期长度,由Content-Length响应头提供。如果没有提供该报头,则值为NSURLSessionTransferSizeUnknown。

NSURLSessionStreamTask - URL会话流任务

基于流的URL会话任务。NSURLSessionStreamTask是NSURLSessionTask的一个具体子类。NSURLSessionStreamTask类中的许多方法都记录在NSURLSessionTask中

NSURLSessionStreamTask类提供了一个通过NSURLSession创建的TCP/IP连接的接口。任务可以使用streamTaskWithHostName:port:方法和streamTaskWithNetService:方法从NSURLSession中创建。它们也可能是通过HTTP Upgrade:响应标头和适当使用NSURLSessionConfiguration的HTTPShouldUsePipelining选项来升级NSURLSessionDataTask的结果。

有关Upgrade:报头的信息,需要参阅RFC 2817和RFC 6455。

NSURLSessionStreamTask对象执行异步读写,这些读写在会话代理队列中排队并串行执行。如果任务完成,则执行会话处理程序。如果任务被取消,所有进入队列的读和写将调用它们的完成处理程序,并返回相应的错误。

当使用接受NSStream对象的Api时,可以通过调用captureStreams方法从NSURLSessionStreamTask对象创建NSInputStream和NSOutputStream对象。

- (void)readDataOfMinLength:(NSUInteger)minBytes maxLength:(NSUInteger)maxBytes timeout:(NSTimeInterval)timeout completionHandler:(void (NS_SWIFT_SENDABLE ^) (NSData * _Nullable_result data, BOOL atEOF, NSError * _Nullable error))completionHandler;

函数描述读取最少minBytes或最多maxBytes字节,并使用数据或错误调用会话代理队列上的完成处理程序。如果发生错误,新的读取请求将立即出错,任何未完成的读取也将失败。

参数 :

minBytes :读取的最小字节数。

maxBytes :要读取的最大字节数。

timeout :读取字节的超时。如果读取没有在指定的时间间隔内完成,则取消读取,并调用completionHandler并返回错误。传递0可以防止读取超时。

completionHandler :当读取所有字节或发生错误时调用的完成处理程序。此处理程序在代理队列上执行。这个完成处理程序接受以下参数:

  • data :从流中读取的数据。
  • atEOF :流是否到达文件结束(EOF),这样就不能再读取数据了。
  • error :一个错误对象,指示读取失败的原因,如果读取成功则为nil。
- (void)writeData:(NSData *)data timeout:(NSTimeInterval)timeout completionHandler:(void (NS_SWIFT_SENDABLE ^) (NSError * _Nullable error))completionHandler;

函数描述将数据完全写入底层套接字。如果所有的字节在超时之前还没有被写入,则会发生超时错误。调用完成处理程序并不保证远程端已经接收到所有字节,只保证它们已经被写入内核。

参数 :

data :要写入的数据。

timeout :写入字节的超时。如果写入操作没有在指定的时间间隔内完成,写入操作将被取消,completionHandler将被调用并返回一个错误。通过0来防止写入超时。

completionHandler :当写入所有字节或发生错误时调用的完成处理程序。此处理程序在代理队列上执行。这个完成处理程序接受以下参数:

  • error :一个错误对象,指示写入失败的原因,如果写入成功则为nil。
- (void)captureStreams;

函数描述完成任何已经进入队列的读写,然后调用URLSession:streamTask:didBecomeInputStream:outputStream: 代理方法。

- (void)closeWrite;

函数描述完成所有排队的读写,然后关闭底层套接字的写入端。在调用该方法后,可以继续使用readDataOfMinLength:maxLength:timeout:completionHandler: 该方法读取数据。但任何对writeData:timeout:completionHandler: 方法的调用都将导致错误。由于服务器可能会继续向客户端写入字节,因此建议继续读取,直到流到达文件结束(EOF)。

- (void)closeRead;

函数描述完成所有排队的读写,然后关闭底层套接字的读取端。在调用该方法后,可以继续使用writeData:timeout:completionHandler: 方法写入数据。但任何对readDataOfMinLength:maxLength:timeout:completionHandler: 方法的调用都将导致错误。

- (void)startSecureConnection;

函数描述完成任何排队的读写,并建立安全连接。如果需要身份验证,会回调会话代理的URLSession:task:didReceiveChallenge:completionHandler: 方法。

NSURLSessionStreamDelegate - 处理流任务的协议

一种协议,它定义了NSURLSession实例在其代理上调用的方法,以处理特定于流任务的任务级事件。同时遵循了NSURLSessionTaskDelegate协议

除此协议中的方法外,还需确保实现NSURLSessionTaskDelegate和NSURLSessionDelegate协议中的方法来分别处理所有任务类型和会话级别事件的公共事件。

- (void)URLSession:(NSURLSession *)session readClosedForStreamTask:(NSURLSessionStreamTask *)streamTask;

函数描述通知代理基础套接字的读取端已关闭。即使当前没有正在进行的读取操作,也可以调用此方法。此方法并不表示流已到达文件结束(EOF)。

参数 :

session :包含关闭读取操作的流任务的会话。

streamTask :关闭读取的流任务。

- (void)URLSession:(NSURLSession *)session writeClosedForStreamTask:(NSURLSessionStreamTask *)streamTask;

函数描述通知代理基础套接字的写入端已关闭。即使当前没有正在进行的写操作,也可以调用此方法。

参数 :

session :包含关闭写入操作的流任务的会话。

streamTask :关闭写入的流任务。

- (void)URLSession:(NSURLSession *)session betterRouteDiscoveredForStreamTask:(NSURLSessionStreamTask *)streamTask;

函数描述告诉代理已为流检测到更好的主机路由。当URL加载系统确定有更好的通往端点主机的路由可用时,将调用此方法。例如,当Wi-Fi接口可用时,可以调用此方法。应该考虑完成挂起的工作并创建一个新的流任务,以便在更好的路由可用时利用它们。

参数 :

session :发现更好路由的流任务的会话。

streamTask :发现更好路由的流任务。

- (void)URLSession:(NSURLSession *)session streamTask:(NSURLSessionStreamTask *)streamTask
                                 didBecomeInputStream:(NSInputStream *)inputStream
                                         outputStream:(NSOutputStream *)outputStream;

函数描述通知代理由于流任务调用captureStreams方法,流任务已经完成。此代理方法仅在流任务的所有入队读写完成后才会被调用。

参数 :

session :已完成的流任务的会话。

streamTask :已完成的流任务。

inputStream :创建的输入流。此NSInputStream对象未打开。

outputStream :创建的输出流。此NSOutputStream对象未打开。

NSURLSessionWebSocketTask - - URL会话WebSocket任务

通过WebSockets协议标准进行通信的URL会话任务。NSURLSessionWebSocketTask是NSURLSessionTask的一个具体子类,它以WebSocket帧的形式在TCP和TLS上提供面向消息的传输协议。它遵循RFC 6455中定义的WebSocket协议

你可以用ws:或wss: URL创建一个NSURLSessionWebSocketTask。创建任务时,还可以提供一个协议列表,以便在握手阶段发布。一旦握手完成,应用程序通过会话的代理接收通知。

使用sendMessage:completionHandler:方法发送数据,用receiveMessageWithCompletionHandler:方法接收数据。该任务异步执行读写,并允许您发送和接收包含二进制帧和UTF-8编码文本帧的消息。该任务将在握手完成之前执行的任何读取或写入排入队列,并在握手完成后执行它们。

NSURLSessionWebSocketTask 与其他类型的任务一样,使用NSURLSessionTaskDelegate中的方法支持重定向和身份验证。WebSocket任务在完成握手之前调用重定向和身份验证代理方法。WebSocket任务还通过将cookie存储到会话配置的HTTPCookieStorage来支持cookie,并将cookie附加到传出的HTTP握手请求。

@property NSInteger maximumMessageSize;

属性描述出错前要缓冲的最大字节数。这包括来自连续帧的所有字节的总和。如果达到此值,接收调用将出错。

@property (readonly) NSURLSessionWebSocketCloseCode closeCode; 

属性描述可以随时查询任务的结束代码。任务未关闭时,将设置为NSURLSessionWebSocketCloseCodeInvalid。

@property (nullable, readonly, copy) NSData *closeReason;

属性描述可以随时查询任务的关闭原因。nil值表示没有任务关闭或任务仍在运行。

- (void)sendMessage:(NSURLSessionWebSocketMessage *)message completionHandler:(void (NS_SWIFT_SENDABLE ^)(NSError * _Nullable error))completionHandler;

函数描述发送WebSocket消息。如果在发送消息时发生错误,任何未完成的工作也将失败。

参数 :

message :要发送的WebSocket消息。

completionHandler :一个接收NSError的块,表示在发送时遇到错误,如果没有发生错误则为nil。

- (void)receiveMessageWithCompletionHandler:(void (NS_SWIFT_SENDABLE ^)(NSURLSessionWebSocketMessage * _Nullable message, NSError * _Nullable error))completionHandler;

函数描述接收WebSocket消息。如果任务在缓冲帧时达到最大MessageSize,则此调用将失败并返回错误。

参数 :

completionHandler :完成处理程序。这个完成处理程序接受以下参数:

  • message :WebSocket消息。
  • error :接收消息时遇到错误的NSError。如果没有发生错误,则错误为nil。
- (void)sendPingWithPongReceiveHandler:(void (NS_SWIFT_SENDABLE ^)(NSError * _Nullable error))pongReceiveHandler;

函数描述处理从服务器接收到pong。当发送多个ping时,任务总是按照发送ping的顺序调用pongReceiveHandler。

参数 :

pongReceiveHandler :任务从服务器接收到pong时调用的块。该块接收一个NSError,该NSError指示连接丢失或其他错误,如果没有错误,则为nil。

- (void)cancelWithCloseCode:(NSURLSessionWebSocketCloseCode)closeCode reason:(nullable NSData *)reason;

函数描述关闭链接,并传递关闭原因。如果在任务上调用cancel而不是这个方法,它会发送一个取消帧,没有关闭码或原因。

参数 :

closeCode :一个NSURLSessionWebSocketCloseCode枚举值,表示关闭连接的原因。

reason :可选的进一步来解释结束的信息。此参数的值由客户端定义,而不是由标准定义。

NSURLSessionWebSocketDelegate - 处理WebSocket任务的协议

一种协议,定义了NSURLSession实例调用其代理来处理特定于WebSocket任务的任务级事件的方法。同时遵循了NSURLSessionTaskDelegate协议。

- (void)URLSession:(NSURLSession *)session webSocketTask:(NSURLSessionWebSocketTask *)webSocketTask didOpenWithProtocol:(nullable NSString *) protocol;

函数描述:通知代理WebSocket任务成功地与端点协商握手,指示协商的协议。如果握手失败,则任务不会调用此代理方法。

参数 :

session :打开的WebSocket任务的会话。

webSocketTask :打开的WebSocket任务。

protocol :在握手阶段选择的协议。如果服务器没有选择协议,或者客户端在创建任务时没有发布协议,则此参数为nil。

- (void)URLSession:(NSURLSession *)session webSocketTask:(NSURLSessionWebSocketTask *)webSocketTask didCloseWithCode:(NSURLSessionWebSocketCloseCode)closeCode reason:(nullable NSData *)reason;

函数描述:通知代理WebSocket任务从服务器端点收到关闭帧,可以选择包含来自服务器的关闭代码和原因。

参数 :

session :WebSocket任务关闭的会话。

webSocketTask :关闭的WebSocket任务。

closeCode :由服务器提供的关闭代码。如果关闭帧不包含关闭代码,则此值为nil。

reason :由服务器提供的关闭原因。如果关闭帧不包含原因,则此值为nil。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,099评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,828评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,540评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,848评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,971评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,132评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,193评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,934评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,376评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,687评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,846评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,537评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,175评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,887评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,134评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,674评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,741评论 2 351

推荐阅读更多精彩内容