/* default timeout for requests. This will cause a timeout if no data is transmitted *for the given timeout value, and is reset whenever data is transmitted. */ @propertyNSTimeInterval timeoutIntervalForRequest; // 超时时长
/* allow request to route over cellular. */ @propertyBOOL allowsCellularAccess; // 是否允许蜂窝网路
/* allows background tasks to be scheduled at the discretion of the system for optimal performance. */ // 数据量大时,让系统自主优化后台任务(比如连上WiFi再开始传输) @property (getter=isDiscretionary) BOOL discretionary;
/* The maximum number of simultanous persistent connections per host */ @propertyNSInteger HTTPMaximumConnectionsPerHost; // 单个主机允许的最大同时并发连接数
/* The cookie storage object to use, or nil to indicate that no cookies should be handled */ @property (nullable, retain) NSHTTPCookieStorage *HTTPCookieStorage;
/* The credential storage object, or nil to indicate that no credential storage is to be used */ @property (nullable, retain) NSURLCredentialStorage *URLCredentialStorage;
/* The URL resource cache, or nil to indicate that no caching is to be performed */ @property (nullable, retain) NSURLCache *URLCache;
The session object keeps a strong reference to the delegate until your app exits or explicitly invalidates the session. If you do not invalidate the session by calling the invalidateAndCancel or finishTasksAndInvalidate method, your app leaks memory until it exits.
An operation queue for scheduling the delegate calls and completion handlers. The queue should be a serial queue, in order to ensure the correct ordering of callbacks. If nil, the session creates a serial operation queue for performing all delegate method calls and completion handler calls.
/* -finishTasksAndInvalidate returns immediately and existing tasks will be allowed * to run to completion. New tasks may not be created. The session * will continueto make delegate callbacks until URLSession:didBecomeInvalidWithError: * has been issued. * * -finishTasksAndInvalidate and -invalidateAndCancel donot * have any effect on the shared session singleton. * * When invalidating a background session, it isnot 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;
/* The last message a session receives. A session will only become * invalid because of a systemic error or when it has been * explicitly invalidated, in which case the error parameter will be nil. */ - (void)URLSession:(NSURLSession *)session didBecomeInvalidWithError:(nullableNSError *)error;
/* If implemented, when a connection level authentication challenge * has occurred, this delegate will be given the opportunity to * provide authentication credentials to the underlying * connection. Some types of authentication will apply to more than * one request on a given connection to a server (SSL Server Trust * challenges). If this delegate message is not implemented, the * behavior will be to use the default handling, which may involve user * interaction. */ - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler;
/* 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; @end
@property (readonly) NSUInteger taskIdentifier; /* an identifier for this task, assigned by and unique to the owning session */ @property (nullable, readonly, copy) NSURLRequest *originalRequest; /* may be nil if this is a stream task */ @property (nullable, readonly, copy) NSURLRequest *currentRequest; /* may differ from originalRequest due to http server redirection */ @property (nullable, readonly, copy) NSURLResponse *response; /* may be nil if no response has been received */
/* * NSProgress object which represents the task progress. * It can be used for task progress tracking. */ @property (readonly, strong) NSProgress *progress API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));
/* * Start the network load for this task no earlier than the specified date. If * not specified, no start delay is used. * * Only applies to tasks created from background NSURLSession instances; has no * effect for tasks created from other session types. */ @property (nullable, copy) NSDate *earliestBeginDate API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));
/* * The number of bytes that the client expects (a best-guess upper-bound) will * be sent and received by this task. These values are used by system scheduling * policy. If unspecified, NSURLSessionTransferSizeUnknown is used. */ @property int64_t countOfBytesClientExpectsToSend API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)); @property int64_t countOfBytesClientExpectsToReceive API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));
/* Byte count properties may be zero if no body is expected, * or NSURLSessionTransferSizeUnknown if it is not possible * to know how many bytes will be transferred. */
/* number of body bytes already received */ @property (readonly) int64_t countOfBytesReceived;
/* number of body bytes already sent */ @property (readonly) int64_t countOfBytesSent;
/* number of body bytes we expect to send, derived from the Content-Length of the HTTP request */ @property (readonly) int64_t countOfBytesExpectedToSend;
/* number of byte bytes we expect to receive, usually derived from the Content-Length header of an HTTP response. */ @property (readonly) int64_t countOfBytesExpectedToReceive;
/* * The taskDescription property is available for the developer to * provide a descriptive label for the task. */ @property (nullable, copy) NSString *taskDescription;
/* * The current state of the task within the session. */ @property (readonly) NSURLSessionTaskState state;
/* * The error, if any, delivered via -URLSession:task:didCompleteWithError: * This property will be nil in the event that no error occured. */ @property (nullable, readonly, copy) NSError *error;
/* -cancel returns immediately, but marks a task as being canceled. * The task will signal -URLSession:task:didCompleteWithError: with an * error value of { NSURLErrorDomain, NSURLErrorCancelled }. In some * cases, the task may signal other work before it acknowledges the * cancelation. -cancel may be sent to a task that has been suspended. */ - (void)cancel;
/* * Suspending a task will prevent the NSURLSession from continuing to * load data. There may still be delegate calls made on behalf of * this task (for instance, to report data received while suspending) * but no further transmissions will be made on behalf of the task * until -resume is sent. The timeout timer associated with the task * will be disabled while a task is suspended. -suspend and -resume are * nestable. */ - (void)suspend; - (void)resume;
/* * Sets a scaling factor for the priority of the task. The scaling factor is a * value between 0.0 and 1.0 (inclusive), where 0.0 is considered the lowest * priority and 1.0 is considered the highest. * * The priority is a hint and not a hard requirement of task performance. The * priority of a task may be changed using this API at any time, but not all * protocols support this; in these cases, the last priority that took effect * will be used. * * If no priority is specified, the task will operate with the default priority * as defined by the constant NSURLSessionTaskPriorityDefault. Two additional * priority levels are provided: NSURLSessionTaskPriorityLow and * NSURLSessionTaskPriorityHigh, but use is not restricted to these. */ @propertyfloatpriorityAPI_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));
/* * Messages related to the operation of a specific task. */ @protocolNSURLSessionTaskDelegate <NSURLSessionDelegate> @optional
/* * Sent when the system is ready to begin work for a task with a delayed start * time set (using the earliestBeginDate property). The completionHandler must * be invoked in order for loading to proceed. The disposition provided to the * completion handler continues the load with the original request provided to * the task, replaces the request with the specified task, or cancels the task. * If this delegate is not implemented, loading will proceed with the original * request. * * Recommendation: only implement this delegate if tasks that have the * earliestBeginDate property set may become stale and require alteration prior * to starting the network load. * * If a new request is specified, the allowsCellularAccess property from the * new request will not be used; the allowsCellularAccess property from the * original request will continue to be used. * * Canceling the task is equivalent to calling the task's cancel method; the * URLSession:task:didCompleteWithError: task delegate will be called with error * NSURLErrorCancelled. */ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willBeginDelayedRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLSessionDelayedRequestDisposition disposition, NSURLRequest * _Nullable newRequest))completionHandler API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));
/* * Sent when a task cannot start the network loading process because the current * network connectivity is not available or sufficient for the task's request. * * This delegate will be called at most one time per task, and is only called if * the waitsForConnectivity property in the NSURLSessionConfiguration has been * set to YES. * * This delegate callback will never be called for background sessions, because * the waitForConnectivity property is ignored by those sessions. */ - (void)URLSession:(NSURLSession *)session taskIsWaitingForConnectivity:(NSURLSessionTask *)task API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0));
/* An HTTP request is attempting to perform a redirection to a different * URL. You must invoke the completion routine to allow the * redirection, allow the redirection with a modified request, or * pass nil to the completionHandler to cause the body of the redirection * response to be delivered as the payload of this request. The default * is to follow redirections. * * For tasks in background sessions, redirections will always be followed and this method will not be called. */ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler;
/* The task has received a request specific authentication challenge. * If this delegate is not implemented, the session specific authentication challenge * will *NOT* be called and the behavior will be the same as using the default handling * disposition. */ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler;
/* Sent if a task requires a new, unopened body stream. This may be * necessary when authentication has failed for any request that * involves a body stream. */ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task needNewBodyStream:(void (^)(NSInputStream * _Nullable bodyStream))completionHandler;
/* Sent periodically to notify the delegate of upload progress. This * information is also available as properties of the task. */ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesSent totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend;
/* * Sent when complete statistics information has been collected for the task. */ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));
/* Sent as the last message related to a specific task. Error may be * nil, which implies that no error occurred and this task is complete. */ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(nullableNSError *)error;
/* * Messages related to the operation of a task that delivers data * directly to the delegate. */ @protocolNSURLSessionDataDelegate <NSURLSessionTaskDelegate> @optional /* The task has received a response and no further messages will be * received until the completion block is called. The disposition * allows you to cancel a request or to turn a data task into a * download task. This delegate message is optional - if you do not * implement it, you can get the response as a property of the task. * * This method will not be called for background upload tasks (which cannot be converted to download tasks). */ - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler;
/* Notification that a data task has become a download task. No * future messages will be sent to the data task. */ - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask;
/* * Notification that a data task has become a bidirectional stream * task. No future messages will be sent to the data task. The newly * created streamTask will carry the original request and response as * properties. * * For requests that were pipelined, the stream object will only allow * reading, and the object will immediately issue a * -URLSession:writeClosedForStream:. Pipelining can be disabled for * all requests in a session, or by the NSURLRequest * HTTPShouldUsePipelining property. * * The underlying connection is no longer considered part of the HTTP * connection cache and won't count against the total number of * connections per host. */ - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didBecomeStreamTask:(NSURLSessionStreamTask *)streamTask;
/* Sent when data is available for the delegate to consume. It is * assumed that the delegate will retain and not copy the data. As * the data may be discontiguous, you should use * [NSData enumerateByteRangesUsingBlock:] to access it. */ - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data;
/* Invoke the completion routine with a valid NSCachedURLResponse to * allow the resulting data to be cached, or pass nil to prevent * caching. Note that there is no guarantee that caching will be * attempted for a given resource, and you should not rely on this * message to receive the resource data. */ - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask willCacheResponse:(NSCachedURLResponse *)proposedResponse completionHandler:(void (^)(NSCachedURLResponse * _Nullable cachedResponse))completionHandler;
/* 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 { NSLog(@"++++thread on finishEvent:%@",[NSThread currentThread]); // 当前回调可能在私有队列中 需要回到主线程 dispatch_async(dispatch_get_main_queue(), ^{ self.completeBlock(); }); }
The URL session API itself is fully thread-safe. You can freely create sessions and tasks in any thread context. When your delegate methods call the provided completion handlers, the work is automatically scheduled on the correct delegate queue.
The system may call the URLSessionDidFinishEventsForBackgroundURLSession: session delegate method on a secondary thread. However, in iOS, your implementation of that method may need to call a completion handler provided to you in your application:handleEventsForBackgroundURLSession:completionHandler: app delegate method. You must call that completion handler on the main thread.