🪶

What is URLSession?

2024/08/04に公開

URLSession

An object that coordinates a group of related, network data transfer tasks.

URLセッション
関連するネットワークデータ転送タスクのグループを調整するオブジェクト。
https://developer.apple.com/documentation/swiftui/navigationpath/codable/

内部実装のコードを読んでみるが長い💦

/* NSURLSession.h
Copyright (c) 2013-2019, Apple Inc. All rights reserved.
*/

/*

NSURLSession is a replacement API for NSURLConnection. It provides
options that affect the policy of, and various aspects of the
mechanism by which NSURLRequest objects are retrieved from the
network.

An NSURLSession may be bound to a delegate object. The delegate is
invoked for certain events during the lifetime of a session, such as
server authentication or determining whether a resource to be loaded
should be converted into a download.

NSURLSession instances are thread-safe.

The default NSURLSession uses a system provided delegate and is
appropriate to use in place of existing code that uses
+[NSURLConnection sendAsynchronousRequest:queue:completionHandler:]

An NSURLSession creates NSURLSessionTask objects which represent the
action of a resource being loaded. These are analogous to
NSURLConnection objects but provide for more control and a unified
delegate model.

NSURLSessionTask objects are always created in a suspended state and
must be sent the -resume message before they will execute.

Subclasses of NSURLSessionTask are used to syntactically
differentiate between data and file downloads.

An NSURLSessionDataTask receives the resource as a series of calls to
the URLSession:dataTask:didReceiveData: delegate method. This is type of
task most commonly associated with retrieving objects for immediate parsing
by the consumer.

An NSURLSessionUploadTask differs from an NSURLSessionDataTask
in how its instance is constructed. Upload tasks are explicitly created
by referencing a file or data object to upload, or by utilizing the
-URLSession:task:needNewBodyStream: delegate message to supply an upload
body.

An NSURLSessionDownloadTask will directly write the response data to
a temporary file. When completed, the delegate is sent
URLSession:downloadTask:didFinishDownloadingToURL: and given an opportunity
to move this file to a permanent location in its sandboxed container, or to
otherwise read the file. If canceled, an NSURLSessionDownloadTask can
produce a data blob that can be used to resume a download at a later
time.

Beginning with iOS 9 and Mac OS X 10.11, NSURLSessionStream is
available as a task type. This allows for direct TCP/IP connection
to a given host and port with optional secure handshaking and
navigation of proxies. Data tasks may also be upgraded to a
NSURLSessionStream task via the HTTP Upgrade: header and appropriate
use of the pipelining option of NSURLSessionConfiguration. See RFC
2817 and RFC 6455 for information about the Upgrade: header, and
comments below on turning data tasks into stream tasks.

An NSURLSessionWebSocketTask is a task that allows clients to connect to servers supporting
WebSocket. The task will perform the HTTP handshake to upgrade the connection
and once the WebSocket handshake is successful, the client can read and write
messages that will be framed using the WebSocket protocol by the framework.
*/

/* DataTask objects receive the payload through zero or more delegate messages /
/
UploadTask objects receive periodic progress updates but do not return a body /
/
DownloadTask objects represent an active download to disk. They can provide resume data when canceled. /
/
StreamTask objects may be used to create NSInput and NSOutputStreams, or used directly in reading and writing. /
/
WebSocket objects perform a WebSocket handshake with the server and can be used to send and receive WebSocket messages */

/* NSURLSession.h
Copyright (c) 2013-2019, Apple Inc. All rights reserved.
*/

/*

NSURLSession は NSURLConnection に代わる API です。 NSURLSession は
のポリシーや、NSURLRequest オブジェクトが NSURLConnection から取得される仕組みのさまざまな側面に影響を与えるオプションを提供します。
NSURLRequest オブジェクトがネットワークから取得される仕組みの様々な側面に影響を与えるオプションを提供します。
ネットワークから NSURLRequest オブジェクトを取得する仕組みのさまざまな側面に影響を与えるオプションを提供する。

NSURLSession はデリゲートオブジェクトにバインドすることができる。 デリゲートは
デリゲートはセッションの有効期間中の特定のイベント、例えば次のような場合に呼び出される。
サーバーの認証や、ロードされるリソースがダウンロードに変換されるかどうか
をダウンロードに変換するかどうかを決定するときなどです。

NSURLSession インスタンスはスレッドセーフです。

デフォルトの NSURLSession はシステムが提供するデリゲートを使用します。
を使用する既存のコードの代わりに使用するのが適切です。
+[NSURLConnection sendAsynchronousRequest:queue:completionHandler:] を使用する既存のコードの代わりに使用するのが適切です。

NSURLSession は NSURLSessionTask オブジェクトを生成します。
オブジェクトを生成します。 これらは
NSURLConnection オブジェクトに似ていますが、より多くの制御と統一された
デリゲートモデルを提供します。

NSURLSessionTaskオブジェクトは常にサスペンド状態で生成され、実行される前に-resumeメッセージを送らなければならない。
を送る必要があります。

NSURLSessionTask のサブクラスは、データ・ダウンロードとファイル・ダウンロードを構文的に区別するために使用されます。
データ・ダウンロードとファイル・ダウンロードを構文的に区別するために使用されます。

NSURLSessionDataTaskは、リソースを以下の一連の呼び出しとして受け取ります。
URLSession:dataTask:didReceiveData:デリゲートメソッドの一連の呼び出しとしてリソースを受け取ります。 これは
このタイプのタスクは、コンシューマーがすぐに解析できるようにオブジェクトを取得することに最もよく関連付けられます。
コンシューマーによる即時解析のためのオブジェクトの取得に最もよく関連するタスクのタイプです。

NSURLSessionUploadTask は NSURLSessionDataTask とはインスタンスの構築方法が異なります。
とはインスタンスの構築方法が異なります。 アップロードタスクは、ファイルまたはデータオブジェクトを参照することで
アップロードするファイルまたはデータオブジェクトを参照するか、または
-URLSession:task:needNewBodyStream: デリゲートメッセージを使用して、アップロード本体
ボディを提供します。

NSURLSessionDownloadTask はレスポンスデータを直接
に直接書き込みます。 完了すると、デリゲートは
URLSession:downloadTask:didFinishDownloadingToURL:が送信され、このファイルを永続的な場所に移動する機会が与えられます。
このファイルをサンドボックス化されたコンテナの永続的な場所に移動するか、あるいは
ファイルを読み込む機会が与えられる。キャンセルされた場合、NSURLSessionDownloadTaskは、以下のことが可能です。
ダウンロードを後で再開するために使用できるデータ blob を生成できます。
を生成できます。

iOS 9とMac OS X 10.11から、NSURLSessionStreamがタスクタイプとして利用できるようになった。
がタスクタイプとして利用できる。 これにより
オプションでセキュアなハンドシェーキングとプロキシ
プロキシのナビゲーション。 データタスクは
ヘッダーと、HTTP Upgrade: のパイプラインオプションの適切な使用によって、 NSURLSessionStream タスクにアップグレードすることもできる。
ヘッダーと NSURLSessionConfiguration のパイプラインオプションの適切な使用によって NSURLSessionStream タスクにアップグレードすることもできる。 RFC
2817 と RFC 6455 を参照のこと。
データタスクをストリームタスクに変換する方法については、以下のコメントを参照してください。

NSURLSessionWebSocketTask は、クライアントが WebSocket をサポートするサーバーに接続するためのタスクです。
WebSocket をサポートするサーバーにクライアントが接続できるようにするタスクです。このタスクは接続をアップグレードするために HTTP ハンドシェイクを実行します。
WebSocketハンドシェイクが成功すると、クライアントは以下のようなメッセージを読み書きできるようになります。
メッセージはフレームワークによってWebSocketプロトコルを使用してフレーム化されます。
*/

/* DataTask オブジェクトは、0 個以上のデリゲートメッセージを通してペイロードを受け取ります。
/* UploadTask オブジェクトは定期的な進捗アップデートを受け取りますが、ボディは返しません。
/* DownloadTaskオブジェクトは、ディスクへのアクティブなダウンロードを表す。 これらのオブジェクトは、キャンセルされたときにレジュームデータを提供することができる。/
/
StreamTask オブジェクトは、NSInputStreams と NSOutputStreams を作成するために使用されるか、読み書きで直接使用される。/
/
WebSocket オブジェクトはサーバーと WebSocket ハンドシェイクを行い、WebSocket メッセージの送受信に使用できる。

内部実装すごく長いです
@available(iOS 7.0, *)
public let NSURLSessionTransferSizeUnknown: Int64 /* -1LL */

@available(iOS 7.0, *)
open class URLSession : NSObject, @unchecked Sendable {

    
    open class var shared: URLSession { get }

    
    public /*not inherited*/ init(configuration: URLSessionConfiguration)

    public /*not inherited*/ init(configuration: URLSessionConfiguration, delegate: (any URLSessionDelegate)?, delegateQueue queue: OperationQueue?)

    
    open var delegateQueue: OperationQueue { get }

    open var delegate: (any URLSessionDelegate)? { get }

    @NSCopying open var configuration: URLSessionConfiguration { get }

    
    open var sessionDescription: String?

    
    open func finishTasksAndInvalidate()

    
    open func invalidateAndCancel()

    
    open func reset(completionHandler: @escaping @Sendable () -> Void)

    open func reset() async

    open func flush(completionHandler: @escaping @Sendable () -> Void)

    open func flush() async

    
    open func getTasksWithCompletionHandler(_ completionHandler: @escaping @Sendable ([URLSessionDataTask], [URLSessionUploadTask], [URLSessionDownloadTask]) -> Void)

    open var tasks: ([URLSessionDataTask], [URLSessionUploadTask], [URLSessionDownloadTask]) { get async }

    
    @available(iOS 9.0, *)
    open func getAllTasks(completionHandler: @escaping @Sendable ([URLSessionTask]) -> Void)

    @available(iOS 9.0, *)
    open var allTasks: [URLSessionTask] { get async }

    
    open func dataTask(with request: URLRequest) -> URLSessionDataTask

    
    open func dataTask(with url: URL) -> URLSessionDataTask

    
    open func uploadTask(with request: URLRequest, fromFile fileURL: URL) -> URLSessionUploadTask

    
    open func uploadTask(with request: URLRequest, from bodyData: Data) -> URLSessionUploadTask

    
    /// Creates an upload task from a resume data blob. Requires the server to support the latest resumable uploads
    /// Internet-Draft from the HTTP Working Group, found at
    /// https://datatracker.ietf.org/doc/draft-ietf-httpbis-resumable-upload/
    /// If resuming from an upload file, the file must still exist and be unmodified. If the upload cannot be successfully
    /// resumed, URLSession:task:didCompleteWithError: will be called.
    ///
    /// - Parameter resumeData: Resume data blob from an incomplete upload, such as data returned by the cancelByProducingResumeData: method.
    /// - Returns: A new session upload task, or nil if the resumeData is invalid.
    @available(iOS 17.0, *)
    open func uploadTask(withResumeData resumeData: Data) -> URLSessionUploadTask

    
    open func uploadTask(withStreamedRequest request: URLRequest) -> URLSessionUploadTask

    
    open func downloadTask(with request: URLRequest) -> URLSessionDownloadTask

    
    open func downloadTask(with url: URL) -> URLSessionDownloadTask

    
    open func downloadTask(withResumeData resumeData: Data) -> URLSessionDownloadTask

    
    @available(iOS 9.0, *)
    open func streamTask(withHostName hostname: String, port: Int) -> URLSessionStreamTask

    
    @available(iOS, introduced: 9.0, deprecated: 100000, message: "Use nw_connection_t in Network framework instead")
    open func streamTask(with service: NetService) -> URLSessionStreamTask

    
    @available(iOS 13.0, *)
    open func webSocketTask(with url: URL) -> URLSessionWebSocketTask

    
    @available(iOS 13.0, *)
    open func webSocketTask(with url: URL, protocols: [String]) -> URLSessionWebSocketTask

    
    @available(iOS 13.0, *)
    open func webSocketTask(with request: URLRequest) -> URLSessionWebSocketTask

    
    @available(iOS, introduced: 7.0, deprecated: 13.0, message: "Please use +[NSURLSession sessionWithConfiguration:] or other class methods to create instances")
    public init()

    @available(iOS, introduced: 7.0, deprecated: 13.0, message: "Please use +[NSURLSession sessionWithConfiguration:] or other class methods to create instances")
    open class func new() -> Self
}

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension URLSession {

    /// Returns a publisher that wraps a URL session data task for a given URL.
    ///
    /// The publisher publishes data when the task completes, or terminates if the task fails with an error.
    /// - Parameter url: The URL for which to create a data task.
    /// - Returns: A publisher that wraps a data task for the URL.
    public func dataTaskPublisher(for url: URL) -> URLSession.DataTaskPublisher

    /// Returns a publisher that wraps a URL session data task for a given URL request.
    ///
    /// The publisher publishes data when the task completes, or terminates if the task fails with an error.
    /// - Parameter request: The URL request for which to create a data task.
    /// - Returns: A publisher that wraps a data task for the URL request.
    public func dataTaskPublisher(for request: URLRequest) -> URLSession.DataTaskPublisher

    public struct DataTaskPublisher : Publisher, Sendable {

        /// The kind of values published by this publisher.
        public typealias Output = (data: Data, response: URLResponse)

        /// The kind of errors this publisher might publish.
        ///
        /// Use `Never` if this `Publisher` does not publish errors.
        public typealias Failure = URLError

        public let request: URLRequest

        public let session: URLSession

        public init(request: URLRequest, session: URLSession)

        /// Attaches the specified subscriber to this publisher.
        ///
        /// Implementations of ``Publisher`` must implement this method.
        ///
        /// The provided implementation of ``Publisher/subscribe(_:)-4u8kn``calls this method.
        ///
        /// - Parameter subscriber: The subscriber to attach to this ``Publisher``, after which it can receive values.
        public func receive<S>(subscriber: S) where S : Subscriber, S.Failure == URLError, S.Input == (data: Data, response: URLResponse)
    }
}

@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
extension URLSession {

    /// Convenience method to load data using a URLRequest, creates and resumes a URLSessionDataTask internally.
    ///
    /// - Parameter request: The URLRequest for which to load data.
    /// - Parameter delegate: Task-specific delegate.
    /// - Returns: Data and response.
    public func data(for request: URLRequest, delegate: (any URLSessionTaskDelegate)? = nil) async throws -> (Data, URLResponse)

    /// Convenience method to load data using a URL, creates and resumes a URLSessionDataTask internally.
    ///
    /// - Parameter url: The URL for which to load data.
    /// - Parameter delegate: Task-specific delegate.
    /// - Returns: Data and response.
    public func data(from url: URL, delegate: (any URLSessionTaskDelegate)? = nil) async throws -> (Data, URLResponse)

    /// Convenience method to upload data using a URLRequest, creates and resumes a URLSessionUploadTask internally.
    ///
    /// - Parameter request: The URLRequest for which to upload data.
    /// - Parameter fileURL: File to upload.
    /// - Parameter delegate: Task-specific delegate.
    /// - Returns: Data and response.
    public func upload(for request: URLRequest, fromFile fileURL: URL, delegate: (any URLSessionTaskDelegate)? = nil) async throws -> (Data, URLResponse)

    /// Convenience method to upload data using a URLRequest, creates and resumes a URLSessionUploadTask internally.
    ///
    /// - Parameter request: The URLRequest for which to upload data.
    /// - Parameter bodyData: Data to upload.
    /// - Parameter delegate: Task-specific delegate.
    /// - Returns: Data and response.
    public func upload(for request: URLRequest, from bodyData: Data, delegate: (any URLSessionTaskDelegate)? = nil) async throws -> (Data, URLResponse)

    /// Convenience method to download using a URLRequest, creates and resumes a URLSessionDownloadTask internally.
    ///
    /// - Parameter request: The URLRequest for which to download.
    /// - Parameter delegate: Task-specific delegate.
    /// - Returns: Downloaded file URL and response. The file will not be removed automatically.
    public func download(for request: URLRequest, delegate: (any URLSessionTaskDelegate)? = nil) async throws -> (URL, URLResponse)

    /// Convenience method to download using a URL, creates and resumes a URLSessionDownloadTask internally.
    ///
    /// - Parameter url: The URL for which to download.
    /// - Parameter delegate: Task-specific delegate.
    /// - Returns: Downloaded file URL and response. The file will not be removed automatically.
    public func download(from url: URL, delegate: (any URLSessionTaskDelegate)? = nil) async throws -> (URL, URLResponse)

    /// Convenience method to resume download, creates and resumes a URLSessionDownloadTask internally.
    ///
    /// - Parameter resumeData: Resume data from an incomplete download.
    /// - Parameter delegate: Task-specific delegate.
    /// - Returns: Downloaded file URL and response. The file will not be removed automatically.
    public func download(resumeFrom resumeData: Data, delegate: (any URLSessionTaskDelegate)? = nil) async throws -> (URL, URLResponse)

    /// AsyncBytes conforms to AsyncSequence for data delivery. The sequence is single pass. Delegate will not be called for response and data delivery.
    public struct AsyncBytes : AsyncSequence, Sendable {

        /// Underlying data task providing the bytes.
        public var task: URLSessionDataTask { get }

        /// The type of element produced by this asynchronous sequence.
        public typealias Element = UInt8

        /// The type of asynchronous iterator that produces elements of this
        /// asynchronous sequence.
        public typealias AsyncIterator = URLSession.AsyncBytes.Iterator

        @frozen public struct Iterator : AsyncIteratorProtocol, Sendable {

            public typealias Element = UInt8

            /// Asynchronously advances to the next element and returns it, or ends the
            /// sequence if there is no next element.
            /// 
            /// - Returns: The next element, if it exists, or `nil` to signal the end of
            ///   the sequence.
            @inlinable public mutating func next() async throws -> UInt8?
        }

        /// Creates the asynchronous iterator that produces elements of this
        /// asynchronous sequence.
        ///
        /// - Returns: An instance of the `AsyncIterator` type used to produce
        /// elements of the asynchronous sequence.
        public func makeAsyncIterator() -> URLSession.AsyncBytes.Iterator
    }

    /// Returns a byte stream that conforms to AsyncSequence protocol.
    ///
    /// - Parameter request: The URLRequest for which to load data.
    /// - Parameter delegate: Task-specific delegate.
    /// - Returns: Data stream and response.
    public func bytes(for request: URLRequest, delegate: (any URLSessionTaskDelegate)? = nil) async throws -> (URLSession.AsyncBytes, URLResponse)

    /// Returns a byte stream that conforms to AsyncSequence protocol.
    ///
    /// - Parameter url: The URL for which to load data.
    /// - Parameter delegate: Task-specific delegate.
    /// - Returns: Data stream and response.
    public func bytes(from url: URL, delegate: (any URLSessionTaskDelegate)? = nil) async throws -> (URLSession.AsyncBytes, URLResponse)
}

@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
extension URLSession {

    /// Convenience method to load data using a URLRequest, creates and resumes a URLSessionDataTask internally.
    ///
    /// - Parameter request: The URLRequest for which to load data.
    /// - Returns: Data and response.
    public func data(for request: URLRequest) async throws -> (Data, URLResponse)

    /// Convenience method to load data using a URL, creates and resumes a URLSessionDataTask internally.
    ///
    /// - Parameter url: The URL for which to load data.
    /// - Returns: Data and response.
    public func data(from url: URL) async throws -> (Data, URLResponse)

    /// Convenience method to upload data using a URLRequest, creates and resumes a URLSessionUploadTask internally.
    ///
    /// - Parameter request: The URLRequest for which to upload data.
    /// - Parameter fileURL: File to upload.
    /// - Returns: Data and response.
    public func upload(for request: URLRequest, fromFile fileURL: URL) async throws -> (Data, URLResponse)

    /// Convenience method to upload data using a URLRequest, creates and resumes a URLSessionUploadTask internally.
    ///
    /// - Parameter request: The URLRequest for which to upload data.
    /// - Parameter bodyData: Data to upload.
    /// - Returns: Data and response.
    public func upload(for request: URLRequest, from bodyData: Data) async throws -> (Data, URLResponse)
}

/*
 * 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.
 */
extension URLSession {

    /*
     * 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.
     */
    open func dataTask(with request: URLRequest, completionHandler: @escaping @Sendable (Data?, URLResponse?, (any Error)?) -> Void) -> URLSessionDataTask

    open func dataTask(with url: URL, completionHandler: @escaping @Sendable (Data?, URLResponse?, (any Error)?) -> Void) -> URLSessionDataTask

    
    /*
     * upload convenience method.
     */
    open func uploadTask(with request: URLRequest, fromFile fileURL: URL, completionHandler: @escaping @Sendable (Data?, URLResponse?, (any Error)?) -> Void) -> URLSessionUploadTask

    open func uploadTask(with request: URLRequest, from bodyData: Data?, completionHandler: @escaping @Sendable (Data?, URLResponse?, (any Error)?) -> Void) -> URLSessionUploadTask

    
    /// Creates a URLSessionUploadTask from a resume data blob. If resuming from an upload
    /// file, the file must still exist and be unmodified.
    ///
    /// - Parameter resumeData: Resume data blob from an incomplete upload, such as data returned by the cancelByProducingResumeData: method.
    /// - Parameter completionHandler: The completion handler to call when the load request is complete.
    /// - Returns: A new session upload task, or nil if the resumeData is invalid.
    @available(iOS 17.0, *)
    open func uploadTask(withResumeData resumeData: Data, completionHandler: @escaping @Sendable (Data?, URLResponse?, (any Error)?) -> Void) -> URLSessionUploadTask

    
    /*
     * 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.
     */
    open func downloadTask(with request: URLRequest, completionHandler: @escaping @Sendable (URL?, URLResponse?, (any Error)?) -> Void) -> URLSessionDownloadTask

    open func downloadTask(with url: URL, completionHandler: @escaping @Sendable (URL?, URLResponse?, (any Error)?) -> Void) -> URLSessionDownloadTask

    open func downloadTask(withResumeData resumeData: Data, completionHandler: @escaping @Sendable (URL?, URLResponse?, (any Error)?) -> Void) -> URLSessionDownloadTask
}
extension URLSessionTask {

    
    @available(iOS 7.0, *)
    public enum State : Int, @unchecked Sendable {

        
        case running = 0

        case suspended = 1

        case canceling = 2

        case completed = 3
    }

    
    /*
     * NSURLSessionTask - a cancelable object that refers to the lifetime
     * of processing a given request.
     */
    
    /* an identifier for this task, assigned by and unique to the owning session */
    /* may be nil if this is a stream task */
    /* may differ from originalRequest due to http server redirection */
    /* may be nil if no response has been received */
    
    /* Sets a task-specific delegate. Methods not implemented on this delegate will
     * still be forwarded to the session delegate.
     *
     * Cannot be modified after task resumes. Not supported on background session.
     *
     * Delegate is strongly referenced until the task completes, after which it is
     * reset to `nil`.
     */
    
    /*
     * NSProgress object which represents the task progress.
     * It can be used for task progress tracking.
     */
    
    /*
     * 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.
     */
    
    /*
     * 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.
     */
    
    /* 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 sent */
    
    /* number of body bytes already received */
    
    /* number of body bytes we expect to send, derived from the Content-Length of the HTTP request */
    
    /* number of byte bytes we expect to receive, usually derived from the Content-Length header of an HTTP response. */
    
    /*
     * The taskDescription property is available for the developer to
     * provide a descriptive label for the task.
     */
    
    /* -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.
     */
    
    /*
     * The current state of the task within the session.
     */
    
    /*
     * The error, if any, delivered via -URLSession:task:didCompleteWithError:
     * This property will be nil in the event that no error occurred.
     */
    
    /*
     * 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. 
     */
    
    /*
     * 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.
     */
    
    /* Provides a hint indicating if incremental delivery of a partial response body
     * would be useful for the application, or if it cannot process the response
     * until it is complete. Indicating that incremental delivery is not desired may
     * improve task performance. For example, if a response cannot be decoded until
     * the entire content is received, set this property to false.
     *
     * Defaults to true unless this task is created with completion-handler based
     * convenience methods, or if it is a download task.
     */
    
    @available(iOS 8.0, *)
    public class let defaultPriority: Float

    @available(iOS 8.0, *)
    public class let lowPriority: Float

    @available(iOS 8.0, *)
    public class let highPriority: Float
}
@available(iOS 7.0, *)
open class URLSessionTask : NSObject, NSCopying, ProgressReporting, @unchecked Sendable {

    open var taskIdentifier: Int { get }

    open var originalRequest: URLRequest? { get }

    open var currentRequest: URLRequest? { get }

    @NSCopying open var response: URLResponse? { get }

    @available(iOS 15.0, *)
    open var delegate: (any URLSessionTaskDelegate)?

    @available(iOS 11.0, *)
    open var progress: Progress { get }

    @available(iOS 11.0, *)
    open var earliestBeginDate: Date?

    @available(iOS 11.0, *)
    open var countOfBytesClientExpectsToSend: Int64

    @available(iOS 11.0, *)
    open var countOfBytesClientExpectsToReceive: Int64

    open var countOfBytesSent: Int64 { get }

    open var countOfBytesReceived: Int64 { get }

    open var countOfBytesExpectedToSend: Int64 { get }

    open var countOfBytesExpectedToReceive: Int64 { get }

    open var taskDescription: String?

    open func cancel()

    open var state: URLSessionTask.State { get }

    open var error: (any Error)? { get }

    open func suspend()

    open func resume()

    @available(iOS 8.0, *)
    open var priority: Float

    @available(iOS 14.5, *)
    open var prefersIncrementalDelivery: Bool

    @available(iOS, introduced: 7.0, deprecated: 13.0, message: "Not supported")
    public init()

    @available(iOS, introduced: 7.0, deprecated: 13.0, message: "Not supported")
    open class func new() -> Self
}

@available(iOS 7.0, *)
open class URLSessionDataTask : URLSessionTask, @unchecked Sendable {

    
    @available(iOS, introduced: 7.0, deprecated: 13.0, message: "Please use -[NSURLSession dataTaskWithRequest:] or other NSURLSession methods to create instances")
    public init()

    @available(iOS, introduced: 7.0, deprecated: 13.0, message: "Please use -[NSURLSession dataTaskWithRequest:] or other NSURLSession methods to create instances")
    open class func new() -> Self
}

@available(iOS 7.0, *)
open class URLSessionUploadTask : URLSessionDataTask, @unchecked Sendable {

    
    @available(iOS, introduced: 7.0, deprecated: 13.0, message: "Please use -[NSURLSession uploadTaskWithStreamedRequest:] or other NSURLSession methods to create instances")
    public init()

    @available(iOS, introduced: 7.0, deprecated: 13.0, message: "Please use -[NSURLSession uploadTaskWithStreamedRequest:] or other NSURLSession methods to create instances")
    open class func new() -> Self

    
    /// Cancels an upload and calls the completion handler with resume data for later use.
    /// resumeData will be nil if the server does not support the latest resumable uploads
    /// Internet-Draft from the HTTP Working Group, found at
    /// https://datatracker.ietf.org/doc/draft-ietf-httpbis-resumable-upload/
    ///
    /// - Parameter completionHandler: The completion handler to call when the upload has been successfully canceled.
    @available(iOS 17.0, *)
    open func cancel(byProducingResumeData completionHandler: @escaping @Sendable (Data?) -> Void)

    /// Cancels an upload and calls the completion handler with resume data for later use.
    /// resumeData will be nil if the server does not support the latest resumable uploads
    /// Internet-Draft from the HTTP Working Group, found at
    /// https://datatracker.ietf.org/doc/draft-ietf-httpbis-resumable-upload/
    ///
    /// - Parameter completionHandler: The completion handler to call when the upload has been successfully canceled.
    @available(iOS 17.0, *)
    open func cancelByProducingResumeData() async -> Data?
}

@available(iOS 7.0, *)
open class URLSessionDownloadTask : URLSessionTask, @unchecked Sendable {

    
    open func cancel(byProducingResumeData completionHandler: @escaping @Sendable (Data?) -> Void)

    open func cancelByProducingResumeData() async -> Data?

    
    @available(iOS, introduced: 7.0, deprecated: 13.0, message: "Please use -[NSURLSession downloadTaskWithRequest:] or other NSURLSession methods to create instances")
    public init()

    @available(iOS, introduced: 7.0, deprecated: 13.0, message: "Please use -[NSURLSession downloadTaskWithRequest:] or other NSURLSession methods to create instances")
    open class func new() -> Self
}

HTTP GETするときだとこのコードを使った

sharedというプロパティにアクセスして、そこから、extension URLSessionのメソッドを使う。

@available(iOS 7.0, *)
open class URLSession : NSObject, @unchecked Sendable {

    
    open class var shared: URLSession { get }

今回の実装だと、func dataTask()というメソッドを呼び出していた。

extension URLSession {

    /*
     * 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.
     */
    open func dataTask(with request: URLRequest, completionHandler: @escaping @Sendable (Data?, URLResponse?, (any Error)?) -> Void) -> URLSessionDataTask

    open func dataTask(with url: URL, completionHandler: @escaping @Sendable (Data?, URLResponse?, (any Error)?) -> Void) -> URLSessionDataTask

まとめ

長くなりましたが、URLSessionについて解説いたしました。

Discussion