//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ffi::*;
use core::ptr::NonNull;
use objc2::__framework_prelude::*;

use crate::*;

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessiontransfersizeunknown?language=objc)
    pub static NSURLSessionTransferSizeUnknown: i64;
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsession?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct NSURLSession;
);

unsafe impl Send for NSURLSession {}

unsafe impl Sync for NSURLSession {}

extern_conformance!(
    unsafe impl NSObjectProtocol for NSURLSession {}
);

impl NSURLSession {
    extern_methods!(
        #[unsafe(method(sharedSession))]
        #[unsafe(method_family = none)]
        pub fn sharedSession() -> Retained<NSURLSession>;

        #[unsafe(method(sessionWithConfiguration:))]
        #[unsafe(method_family = none)]
        pub fn sessionWithConfiguration(
            configuration: &NSURLSessionConfiguration,
        ) -> Retained<NSURLSession>;

        #[cfg(feature = "NSOperation")]
        /// # Safety
        ///
        /// `queue` possibly has additional threading requirements.
        #[unsafe(method(sessionWithConfiguration:delegate:delegateQueue:))]
        #[unsafe(method_family = none)]
        pub unsafe fn sessionWithConfiguration_delegate_delegateQueue(
            configuration: &NSURLSessionConfiguration,
            delegate: Option<&ProtocolObject<dyn NSURLSessionDelegate>>,
            queue: Option<&NSOperationQueue>,
        ) -> Retained<NSURLSession>;

        #[cfg(feature = "NSOperation")]
        #[unsafe(method(delegateQueue))]
        #[unsafe(method_family = none)]
        pub fn delegateQueue(&self) -> Retained<NSOperationQueue>;

        #[unsafe(method(delegate))]
        #[unsafe(method_family = none)]
        pub fn delegate(&self) -> Option<Retained<ProtocolObject<dyn NSURLSessionDelegate>>>;

        #[unsafe(method(configuration))]
        #[unsafe(method_family = none)]
        pub fn configuration(&self) -> Retained<NSURLSessionConfiguration>;

        #[cfg(feature = "NSString")]
        #[unsafe(method(sessionDescription))]
        #[unsafe(method_family = none)]
        pub fn sessionDescription(&self) -> Option<Retained<NSString>>;

        #[cfg(feature = "NSString")]
        /// Setter for [`sessionDescription`][Self::sessionDescription].
        ///
        /// This is [copied][crate::NSCopying::copy] when set.
        #[unsafe(method(setSessionDescription:))]
        #[unsafe(method_family = none)]
        pub fn setSessionDescription(&self, session_description: Option<&NSString>);

        #[unsafe(method(finishTasksAndInvalidate))]
        #[unsafe(method_family = none)]
        pub fn finishTasksAndInvalidate(&self);

        #[unsafe(method(invalidateAndCancel))]
        #[unsafe(method_family = none)]
        pub fn invalidateAndCancel(&self);

        #[cfg(feature = "block2")]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[unsafe(method(resetWithCompletionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn resetWithCompletionHandler(
            &self,
            completion_handler: &block2::DynBlock<dyn Fn()>,
        );

        #[cfg(feature = "block2")]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[unsafe(method(flushWithCompletionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn flushWithCompletionHandler(
            &self,
            completion_handler: &block2::DynBlock<dyn Fn()>,
        );

        #[cfg(all(feature = "NSArray", feature = "block2"))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[unsafe(method(getTasksWithCompletionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn getTasksWithCompletionHandler(
            &self,
            completion_handler: &block2::DynBlock<
                dyn Fn(
                    NonNull<NSArray<NSURLSessionDataTask>>,
                    NonNull<NSArray<NSURLSessionUploadTask>>,
                    NonNull<NSArray<NSURLSessionDownloadTask>>,
                ),
            >,
        );

        #[cfg(all(feature = "NSArray", feature = "block2"))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[unsafe(method(getAllTasksWithCompletionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn getAllTasksWithCompletionHandler(
            &self,
            completion_handler: &block2::DynBlock<dyn Fn(NonNull<NSArray<NSURLSessionTask>>)>,
        );

        #[cfg(feature = "NSURLRequest")]
        #[unsafe(method(dataTaskWithRequest:))]
        #[unsafe(method_family = none)]
        pub fn dataTaskWithRequest(&self, request: &NSURLRequest)
            -> Retained<NSURLSessionDataTask>;

        #[cfg(feature = "NSURL")]
        #[unsafe(method(dataTaskWithURL:))]
        #[unsafe(method_family = none)]
        pub fn dataTaskWithURL(&self, url: &NSURL) -> Retained<NSURLSessionDataTask>;

        #[cfg(all(feature = "NSURL", feature = "NSURLRequest"))]
        #[unsafe(method(uploadTaskWithRequest:fromFile:))]
        #[unsafe(method_family = none)]
        pub fn uploadTaskWithRequest_fromFile(
            &self,
            request: &NSURLRequest,
            file_url: &NSURL,
        ) -> Retained<NSURLSessionUploadTask>;

        #[cfg(all(feature = "NSData", feature = "NSURLRequest"))]
        #[unsafe(method(uploadTaskWithRequest:fromData:))]
        #[unsafe(method_family = none)]
        pub fn uploadTaskWithRequest_fromData(
            &self,
            request: &NSURLRequest,
            body_data: &NSData,
        ) -> Retained<NSURLSessionUploadTask>;

        #[cfg(feature = "NSData")]
        /// 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.
        #[unsafe(method(uploadTaskWithResumeData:))]
        #[unsafe(method_family = none)]
        pub fn uploadTaskWithResumeData(
            &self,
            resume_data: &NSData,
        ) -> Retained<NSURLSessionUploadTask>;

        #[cfg(feature = "NSURLRequest")]
        #[unsafe(method(uploadTaskWithStreamedRequest:))]
        #[unsafe(method_family = none)]
        pub fn uploadTaskWithStreamedRequest(
            &self,
            request: &NSURLRequest,
        ) -> Retained<NSURLSessionUploadTask>;

        #[cfg(feature = "NSURLRequest")]
        #[unsafe(method(downloadTaskWithRequest:))]
        #[unsafe(method_family = none)]
        pub fn downloadTaskWithRequest(
            &self,
            request: &NSURLRequest,
        ) -> Retained<NSURLSessionDownloadTask>;

        #[cfg(feature = "NSURL")]
        #[unsafe(method(downloadTaskWithURL:))]
        #[unsafe(method_family = none)]
        pub fn downloadTaskWithURL(&self, url: &NSURL) -> Retained<NSURLSessionDownloadTask>;

        #[cfg(feature = "NSData")]
        #[unsafe(method(downloadTaskWithResumeData:))]
        #[unsafe(method_family = none)]
        pub fn downloadTaskWithResumeData(
            &self,
            resume_data: &NSData,
        ) -> Retained<NSURLSessionDownloadTask>;

        #[cfg(feature = "NSString")]
        #[unsafe(method(streamTaskWithHostName:port:))]
        #[unsafe(method_family = none)]
        pub fn streamTaskWithHostName_port(
            &self,
            hostname: &NSString,
            port: NSInteger,
        ) -> Retained<NSURLSessionStreamTask>;

        #[cfg(feature = "NSNetServices")]
        #[deprecated = "Use nw_connection_t in Network framework instead"]
        #[unsafe(method(streamTaskWithNetService:))]
        #[unsafe(method_family = none)]
        pub fn streamTaskWithNetService(
            &self,
            service: &NSNetService,
        ) -> Retained<NSURLSessionStreamTask>;

        #[cfg(feature = "NSURL")]
        #[unsafe(method(webSocketTaskWithURL:))]
        #[unsafe(method_family = none)]
        pub fn webSocketTaskWithURL(&self, url: &NSURL) -> Retained<NSURLSessionWebSocketTask>;

        #[cfg(all(feature = "NSArray", feature = "NSString", feature = "NSURL"))]
        #[unsafe(method(webSocketTaskWithURL:protocols:))]
        #[unsafe(method_family = none)]
        pub fn webSocketTaskWithURL_protocols(
            &self,
            url: &NSURL,
            protocols: &NSArray<NSString>,
        ) -> Retained<NSURLSessionWebSocketTask>;

        #[cfg(feature = "NSURLRequest")]
        #[unsafe(method(webSocketTaskWithRequest:))]
        #[unsafe(method_family = none)]
        pub fn webSocketTaskWithRequest(
            &self,
            request: &NSURLRequest,
        ) -> Retained<NSURLSessionWebSocketTask>;

        #[deprecated = "Please use +[NSURLSession sessionWithConfiguration:] or other class methods to create instances"]
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;

        #[deprecated = "Please use +[NSURLSession sessionWithConfiguration:] or other class methods to create instances"]
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new() -> Retained<Self>;
    );
}

/// NSURLSessionAsynchronousConvenience.
impl NSURLSession {
    extern_methods!(
        #[cfg(all(
            feature = "NSData",
            feature = "NSError",
            feature = "NSURLRequest",
            feature = "NSURLResponse",
            feature = "block2"
        ))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[unsafe(method(dataTaskWithRequest:completionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn dataTaskWithRequest_completionHandler(
            &self,
            request: &NSURLRequest,
            completion_handler: &block2::DynBlock<
                dyn Fn(*mut NSData, *mut NSURLResponse, *mut NSError),
            >,
        ) -> Retained<NSURLSessionDataTask>;

        #[cfg(all(
            feature = "NSData",
            feature = "NSError",
            feature = "NSURL",
            feature = "NSURLResponse",
            feature = "block2"
        ))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[unsafe(method(dataTaskWithURL:completionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn dataTaskWithURL_completionHandler(
            &self,
            url: &NSURL,
            completion_handler: &block2::DynBlock<
                dyn Fn(*mut NSData, *mut NSURLResponse, *mut NSError),
            >,
        ) -> Retained<NSURLSessionDataTask>;

        #[cfg(all(
            feature = "NSData",
            feature = "NSError",
            feature = "NSURL",
            feature = "NSURLRequest",
            feature = "NSURLResponse",
            feature = "block2"
        ))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[unsafe(method(uploadTaskWithRequest:fromFile:completionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn uploadTaskWithRequest_fromFile_completionHandler(
            &self,
            request: &NSURLRequest,
            file_url: &NSURL,
            completion_handler: &block2::DynBlock<
                dyn Fn(*mut NSData, *mut NSURLResponse, *mut NSError),
            >,
        ) -> Retained<NSURLSessionUploadTask>;

        #[cfg(all(
            feature = "NSData",
            feature = "NSError",
            feature = "NSURLRequest",
            feature = "NSURLResponse",
            feature = "block2"
        ))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[unsafe(method(uploadTaskWithRequest:fromData:completionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn uploadTaskWithRequest_fromData_completionHandler(
            &self,
            request: &NSURLRequest,
            body_data: Option<&NSData>,
            completion_handler: &block2::DynBlock<
                dyn Fn(*mut NSData, *mut NSURLResponse, *mut NSError),
            >,
        ) -> Retained<NSURLSessionUploadTask>;

        #[cfg(all(
            feature = "NSData",
            feature = "NSError",
            feature = "NSURLResponse",
            feature = "block2"
        ))]
        /// 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.
        ///
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[unsafe(method(uploadTaskWithResumeData:completionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn uploadTaskWithResumeData_completionHandler(
            &self,
            resume_data: &NSData,
            completion_handler: &block2::DynBlock<
                dyn Fn(*mut NSData, *mut NSURLResponse, *mut NSError),
            >,
        ) -> Retained<NSURLSessionUploadTask>;

        #[cfg(all(
            feature = "NSError",
            feature = "NSURL",
            feature = "NSURLRequest",
            feature = "NSURLResponse",
            feature = "block2"
        ))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[unsafe(method(downloadTaskWithRequest:completionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn downloadTaskWithRequest_completionHandler(
            &self,
            request: &NSURLRequest,
            completion_handler: &block2::DynBlock<
                dyn Fn(*mut NSURL, *mut NSURLResponse, *mut NSError),
            >,
        ) -> Retained<NSURLSessionDownloadTask>;

        #[cfg(all(
            feature = "NSError",
            feature = "NSURL",
            feature = "NSURLResponse",
            feature = "block2"
        ))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[unsafe(method(downloadTaskWithURL:completionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn downloadTaskWithURL_completionHandler(
            &self,
            url: &NSURL,
            completion_handler: &block2::DynBlock<
                dyn Fn(*mut NSURL, *mut NSURLResponse, *mut NSError),
            >,
        ) -> Retained<NSURLSessionDownloadTask>;

        #[cfg(all(
            feature = "NSData",
            feature = "NSError",
            feature = "NSURL",
            feature = "NSURLResponse",
            feature = "block2"
        ))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[unsafe(method(downloadTaskWithResumeData:completionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn downloadTaskWithResumeData_completionHandler(
            &self,
            resume_data: &NSData,
            completion_handler: &block2::DynBlock<
                dyn Fn(*mut NSURL, *mut NSURLResponse, *mut NSError),
            >,
        ) -> Retained<NSURLSessionDownloadTask>;
    );
}

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessiontaskstate?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSURLSessionTaskState(pub NSInteger);
impl NSURLSessionTaskState {
    #[doc(alias = "NSURLSessionTaskStateRunning")]
    pub const Running: Self = Self(0);
    #[doc(alias = "NSURLSessionTaskStateSuspended")]
    pub const Suspended: Self = Self(1);
    #[doc(alias = "NSURLSessionTaskStateCanceling")]
    pub const Canceling: Self = Self(2);
    #[doc(alias = "NSURLSessionTaskStateCompleted")]
    pub const Completed: Self = Self(3);
}

unsafe impl Encode for NSURLSessionTaskState {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for NSURLSessionTaskState {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessiontask?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct NSURLSessionTask;
);

unsafe impl Send for NSURLSessionTask {}

unsafe impl Sync for NSURLSessionTask {}

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl NSCopying for NSURLSessionTask {}
);

#[cfg(feature = "NSObject")]
unsafe impl CopyingHelper for NSURLSessionTask {
    type Result = Self;
}

extern_conformance!(
    unsafe impl NSObjectProtocol for NSURLSessionTask {}
);

#[cfg(feature = "NSProgress")]
extern_conformance!(
    unsafe impl NSProgressReporting for NSURLSessionTask {}
);

impl NSURLSessionTask {
    extern_methods!(
        #[unsafe(method(taskIdentifier))]
        #[unsafe(method_family = none)]
        pub fn taskIdentifier(&self) -> NSUInteger;

        #[cfg(feature = "NSURLRequest")]
        #[unsafe(method(originalRequest))]
        #[unsafe(method_family = none)]
        pub fn originalRequest(&self) -> Option<Retained<NSURLRequest>>;

        #[cfg(feature = "NSURLRequest")]
        #[unsafe(method(currentRequest))]
        #[unsafe(method_family = none)]
        pub fn currentRequest(&self) -> Option<Retained<NSURLRequest>>;

        #[cfg(feature = "NSURLResponse")]
        #[unsafe(method(response))]
        #[unsafe(method_family = none)]
        pub fn response(&self) -> Option<Retained<NSURLResponse>>;

        #[unsafe(method(delegate))]
        #[unsafe(method_family = none)]
        pub fn delegate(&self) -> Option<Retained<ProtocolObject<dyn NSURLSessionTaskDelegate>>>;

        /// Setter for [`delegate`][Self::delegate].
        #[unsafe(method(setDelegate:))]
        #[unsafe(method_family = none)]
        pub fn setDelegate(&self, delegate: Option<&ProtocolObject<dyn NSURLSessionTaskDelegate>>);

        #[cfg(feature = "NSProgress")]
        #[unsafe(method(progress))]
        #[unsafe(method_family = none)]
        pub fn progress(&self) -> Retained<NSProgress>;

        #[cfg(feature = "NSDate")]
        #[unsafe(method(earliestBeginDate))]
        #[unsafe(method_family = none)]
        pub fn earliestBeginDate(&self) -> Option<Retained<NSDate>>;

        #[cfg(feature = "NSDate")]
        /// Setter for [`earliestBeginDate`][Self::earliestBeginDate].
        ///
        /// This is [copied][crate::NSCopying::copy] when set.
        #[unsafe(method(setEarliestBeginDate:))]
        #[unsafe(method_family = none)]
        pub fn setEarliestBeginDate(&self, earliest_begin_date: Option<&NSDate>);

        #[unsafe(method(countOfBytesClientExpectsToSend))]
        #[unsafe(method_family = none)]
        pub fn countOfBytesClientExpectsToSend(&self) -> i64;

        /// Setter for [`countOfBytesClientExpectsToSend`][Self::countOfBytesClientExpectsToSend].
        #[unsafe(method(setCountOfBytesClientExpectsToSend:))]
        #[unsafe(method_family = none)]
        pub fn setCountOfBytesClientExpectsToSend(
            &self,
            count_of_bytes_client_expects_to_send: i64,
        );

        #[unsafe(method(countOfBytesClientExpectsToReceive))]
        #[unsafe(method_family = none)]
        pub fn countOfBytesClientExpectsToReceive(&self) -> i64;

        /// Setter for [`countOfBytesClientExpectsToReceive`][Self::countOfBytesClientExpectsToReceive].
        #[unsafe(method(setCountOfBytesClientExpectsToReceive:))]
        #[unsafe(method_family = none)]
        pub fn setCountOfBytesClientExpectsToReceive(
            &self,
            count_of_bytes_client_expects_to_receive: i64,
        );

        #[unsafe(method(countOfBytesSent))]
        #[unsafe(method_family = none)]
        pub fn countOfBytesSent(&self) -> i64;

        #[unsafe(method(countOfBytesReceived))]
        #[unsafe(method_family = none)]
        pub fn countOfBytesReceived(&self) -> i64;

        #[unsafe(method(countOfBytesExpectedToSend))]
        #[unsafe(method_family = none)]
        pub fn countOfBytesExpectedToSend(&self) -> i64;

        #[unsafe(method(countOfBytesExpectedToReceive))]
        #[unsafe(method_family = none)]
        pub fn countOfBytesExpectedToReceive(&self) -> i64;

        #[cfg(feature = "NSString")]
        #[unsafe(method(taskDescription))]
        #[unsafe(method_family = none)]
        pub fn taskDescription(&self) -> Option<Retained<NSString>>;

        #[cfg(feature = "NSString")]
        /// Setter for [`taskDescription`][Self::taskDescription].
        ///
        /// This is [copied][crate::NSCopying::copy] when set.
        #[unsafe(method(setTaskDescription:))]
        #[unsafe(method_family = none)]
        pub fn setTaskDescription(&self, task_description: Option<&NSString>);

        #[unsafe(method(cancel))]
        #[unsafe(method_family = none)]
        pub fn cancel(&self);

        #[unsafe(method(state))]
        #[unsafe(method_family = none)]
        pub fn state(&self) -> NSURLSessionTaskState;

        #[cfg(feature = "NSError")]
        #[unsafe(method(error))]
        #[unsafe(method_family = none)]
        pub fn error(&self) -> Option<Retained<NSError>>;

        #[unsafe(method(suspend))]
        #[unsafe(method_family = none)]
        pub fn suspend(&self);

        #[unsafe(method(resume))]
        #[unsafe(method_family = none)]
        pub fn resume(&self);

        #[unsafe(method(priority))]
        #[unsafe(method_family = none)]
        pub fn priority(&self) -> c_float;

        /// Setter for [`priority`][Self::priority].
        #[unsafe(method(setPriority:))]
        #[unsafe(method_family = none)]
        pub fn setPriority(&self, priority: c_float);

        #[unsafe(method(prefersIncrementalDelivery))]
        #[unsafe(method_family = none)]
        pub fn prefersIncrementalDelivery(&self) -> bool;

        /// Setter for [`prefersIncrementalDelivery`][Self::prefersIncrementalDelivery].
        #[unsafe(method(setPrefersIncrementalDelivery:))]
        #[unsafe(method_family = none)]
        pub fn setPrefersIncrementalDelivery(&self, prefers_incremental_delivery: bool);

        #[deprecated = "Not supported"]
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;

        #[deprecated = "Not supported"]
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new() -> Retained<Self>;
    );
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessiontaskprioritydefault?language=objc)
    pub static NSURLSessionTaskPriorityDefault: c_float;
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessiontaskprioritylow?language=objc)
    pub static NSURLSessionTaskPriorityLow: c_float;
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessiontaskpriorityhigh?language=objc)
    pub static NSURLSessionTaskPriorityHigh: c_float;
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessiondatatask?language=objc)
    #[unsafe(super(NSURLSessionTask, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct NSURLSessionDataTask;
);

unsafe impl Send for NSURLSessionDataTask {}

unsafe impl Sync for NSURLSessionDataTask {}

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl NSCopying for NSURLSessionDataTask {}
);

#[cfg(feature = "NSObject")]
unsafe impl CopyingHelper for NSURLSessionDataTask {
    type Result = Self;
}

extern_conformance!(
    unsafe impl NSObjectProtocol for NSURLSessionDataTask {}
);

#[cfg(feature = "NSProgress")]
extern_conformance!(
    unsafe impl NSProgressReporting for NSURLSessionDataTask {}
);

impl NSURLSessionDataTask {
    extern_methods!(
        #[deprecated = "Please use -[NSURLSession dataTaskWithRequest:] or other NSURLSession methods to create instances"]
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;

        #[deprecated = "Please use -[NSURLSession dataTaskWithRequest:] or other NSURLSession methods to create instances"]
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new() -> Retained<Self>;
    );
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessionuploadtask?language=objc)
    #[unsafe(super(NSURLSessionDataTask, NSURLSessionTask, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct NSURLSessionUploadTask;
);

unsafe impl Send for NSURLSessionUploadTask {}

unsafe impl Sync for NSURLSessionUploadTask {}

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl NSCopying for NSURLSessionUploadTask {}
);

#[cfg(feature = "NSObject")]
unsafe impl CopyingHelper for NSURLSessionUploadTask {
    type Result = Self;
}

extern_conformance!(
    unsafe impl NSObjectProtocol for NSURLSessionUploadTask {}
);

#[cfg(feature = "NSProgress")]
extern_conformance!(
    unsafe impl NSProgressReporting for NSURLSessionUploadTask {}
);

impl NSURLSessionUploadTask {
    extern_methods!(
        #[deprecated = "Please use -[NSURLSession uploadTaskWithStreamedRequest:] or other NSURLSession methods to create instances"]
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;

        #[deprecated = "Please use -[NSURLSession uploadTaskWithStreamedRequest:] or other NSURLSession methods to create instances"]
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new() -> Retained<Self>;

        #[cfg(all(feature = "NSData", feature = "block2"))]
        /// 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.
        ///
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[unsafe(method(cancelByProducingResumeData:))]
        #[unsafe(method_family = none)]
        pub unsafe fn cancelByProducingResumeData(
            &self,
            completion_handler: &block2::DynBlock<dyn Fn(*mut NSData)>,
        );
    );
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessiondownloadtask?language=objc)
    #[unsafe(super(NSURLSessionTask, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct NSURLSessionDownloadTask;
);

unsafe impl Send for NSURLSessionDownloadTask {}

unsafe impl Sync for NSURLSessionDownloadTask {}

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl NSCopying for NSURLSessionDownloadTask {}
);

#[cfg(feature = "NSObject")]
unsafe impl CopyingHelper for NSURLSessionDownloadTask {
    type Result = Self;
}

extern_conformance!(
    unsafe impl NSObjectProtocol for NSURLSessionDownloadTask {}
);

#[cfg(feature = "NSProgress")]
extern_conformance!(
    unsafe impl NSProgressReporting for NSURLSessionDownloadTask {}
);

impl NSURLSessionDownloadTask {
    extern_methods!(
        #[cfg(all(feature = "NSData", feature = "block2"))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[unsafe(method(cancelByProducingResumeData:))]
        #[unsafe(method_family = none)]
        pub unsafe fn cancelByProducingResumeData(
            &self,
            completion_handler: &block2::DynBlock<dyn Fn(*mut NSData)>,
        );

        #[deprecated = "Please use -[NSURLSession downloadTaskWithRequest:] or other NSURLSession methods to create instances"]
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;

        #[deprecated = "Please use -[NSURLSession downloadTaskWithRequest:] or other NSURLSession methods to create instances"]
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new() -> Retained<Self>;
    );
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessionstreamtask?language=objc)
    #[unsafe(super(NSURLSessionTask, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct NSURLSessionStreamTask;
);

unsafe impl Send for NSURLSessionStreamTask {}

unsafe impl Sync for NSURLSessionStreamTask {}

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl NSCopying for NSURLSessionStreamTask {}
);

#[cfg(feature = "NSObject")]
unsafe impl CopyingHelper for NSURLSessionStreamTask {
    type Result = Self;
}

extern_conformance!(
    unsafe impl NSObjectProtocol for NSURLSessionStreamTask {}
);

#[cfg(feature = "NSProgress")]
extern_conformance!(
    unsafe impl NSProgressReporting for NSURLSessionStreamTask {}
);

impl NSURLSessionStreamTask {
    extern_methods!(
        #[cfg(all(
            feature = "NSData",
            feature = "NSDate",
            feature = "NSError",
            feature = "block2"
        ))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[unsafe(method(readDataOfMinLength:maxLength:timeout:completionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn readDataOfMinLength_maxLength_timeout_completionHandler(
            &self,
            min_bytes: NSUInteger,
            max_bytes: NSUInteger,
            timeout: NSTimeInterval,
            completion_handler: &block2::DynBlock<dyn Fn(*mut NSData, Bool, *mut NSError)>,
        );

        #[cfg(all(
            feature = "NSData",
            feature = "NSDate",
            feature = "NSError",
            feature = "block2"
        ))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[unsafe(method(writeData:timeout:completionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn writeData_timeout_completionHandler(
            &self,
            data: &NSData,
            timeout: NSTimeInterval,
            completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
        );

        #[unsafe(method(captureStreams))]
        #[unsafe(method_family = none)]
        pub fn captureStreams(&self);

        #[unsafe(method(closeWrite))]
        #[unsafe(method_family = none)]
        pub fn closeWrite(&self);

        #[unsafe(method(closeRead))]
        #[unsafe(method_family = none)]
        pub fn closeRead(&self);

        #[unsafe(method(startSecureConnection))]
        #[unsafe(method_family = none)]
        pub fn startSecureConnection(&self);

        #[deprecated = "TLS cannot be disabled once it is enabled"]
        #[unsafe(method(stopSecureConnection))]
        #[unsafe(method_family = none)]
        pub fn stopSecureConnection(&self);

        #[deprecated = "Please use -[NSURLSession streamTaskWithHostName:port:] or other NSURLSession methods to create instances"]
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;

        #[deprecated = "Please use -[NSURLSession streamTaskWithHostName:port:] or other NSURLSession methods to create instances"]
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new() -> Retained<Self>;
    );
}

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessionwebsocketmessagetype?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSURLSessionWebSocketMessageType(pub NSInteger);
impl NSURLSessionWebSocketMessageType {
    #[doc(alias = "NSURLSessionWebSocketMessageTypeData")]
    pub const Data: Self = Self(0);
    #[doc(alias = "NSURLSessionWebSocketMessageTypeString")]
    pub const String: Self = Self(1);
}

unsafe impl Encode for NSURLSessionWebSocketMessageType {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for NSURLSessionWebSocketMessageType {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessionwebsocketmessage?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct NSURLSessionWebSocketMessage;
);

unsafe impl Send for NSURLSessionWebSocketMessage {}

unsafe impl Sync for NSURLSessionWebSocketMessage {}

extern_conformance!(
    unsafe impl NSObjectProtocol for NSURLSessionWebSocketMessage {}
);

impl NSURLSessionWebSocketMessage {
    extern_methods!(
        #[cfg(feature = "NSData")]
        #[unsafe(method(initWithData:))]
        #[unsafe(method_family = init)]
        pub fn initWithData(this: Allocated<Self>, data: &NSData) -> Retained<Self>;

        #[cfg(feature = "NSString")]
        #[unsafe(method(initWithString:))]
        #[unsafe(method_family = init)]
        pub fn initWithString(this: Allocated<Self>, string: &NSString) -> Retained<Self>;

        #[unsafe(method(type))]
        #[unsafe(method_family = none)]
        pub fn r#type(&self) -> NSURLSessionWebSocketMessageType;

        #[cfg(feature = "NSData")]
        #[unsafe(method(data))]
        #[unsafe(method_family = none)]
        pub fn data(&self) -> Option<Retained<NSData>>;

        #[cfg(feature = "NSString")]
        #[unsafe(method(string))]
        #[unsafe(method_family = none)]
        pub fn string(&self) -> Option<Retained<NSString>>;

        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;
    );
}

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessionwebsocketclosecode?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSURLSessionWebSocketCloseCode(pub NSInteger);
impl NSURLSessionWebSocketCloseCode {
    #[doc(alias = "NSURLSessionWebSocketCloseCodeInvalid")]
    pub const Invalid: Self = Self(0);
    #[doc(alias = "NSURLSessionWebSocketCloseCodeNormalClosure")]
    pub const NormalClosure: Self = Self(1000);
    #[doc(alias = "NSURLSessionWebSocketCloseCodeGoingAway")]
    pub const GoingAway: Self = Self(1001);
    #[doc(alias = "NSURLSessionWebSocketCloseCodeProtocolError")]
    pub const ProtocolError: Self = Self(1002);
    #[doc(alias = "NSURLSessionWebSocketCloseCodeUnsupportedData")]
    pub const UnsupportedData: Self = Self(1003);
    #[doc(alias = "NSURLSessionWebSocketCloseCodeNoStatusReceived")]
    pub const NoStatusReceived: Self = Self(1005);
    #[doc(alias = "NSURLSessionWebSocketCloseCodeAbnormalClosure")]
    pub const AbnormalClosure: Self = Self(1006);
    #[doc(alias = "NSURLSessionWebSocketCloseCodeInvalidFramePayloadData")]
    pub const InvalidFramePayloadData: Self = Self(1007);
    #[doc(alias = "NSURLSessionWebSocketCloseCodePolicyViolation")]
    pub const PolicyViolation: Self = Self(1008);
    #[doc(alias = "NSURLSessionWebSocketCloseCodeMessageTooBig")]
    pub const MessageTooBig: Self = Self(1009);
    #[doc(alias = "NSURLSessionWebSocketCloseCodeMandatoryExtensionMissing")]
    pub const MandatoryExtensionMissing: Self = Self(1010);
    #[doc(alias = "NSURLSessionWebSocketCloseCodeInternalServerError")]
    pub const InternalServerError: Self = Self(1011);
    #[doc(alias = "NSURLSessionWebSocketCloseCodeTLSHandshakeFailure")]
    pub const TLSHandshakeFailure: Self = Self(1015);
}

unsafe impl Encode for NSURLSessionWebSocketCloseCode {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for NSURLSessionWebSocketCloseCode {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessionwebsockettask?language=objc)
    #[unsafe(super(NSURLSessionTask, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct NSURLSessionWebSocketTask;
);

unsafe impl Send for NSURLSessionWebSocketTask {}

unsafe impl Sync for NSURLSessionWebSocketTask {}

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl NSCopying for NSURLSessionWebSocketTask {}
);

#[cfg(feature = "NSObject")]
unsafe impl CopyingHelper for NSURLSessionWebSocketTask {
    type Result = Self;
}

extern_conformance!(
    unsafe impl NSObjectProtocol for NSURLSessionWebSocketTask {}
);

#[cfg(feature = "NSProgress")]
extern_conformance!(
    unsafe impl NSProgressReporting for NSURLSessionWebSocketTask {}
);

impl NSURLSessionWebSocketTask {
    extern_methods!(
        #[cfg(all(feature = "NSError", feature = "block2"))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[unsafe(method(sendMessage:completionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn sendMessage_completionHandler(
            &self,
            message: &NSURLSessionWebSocketMessage,
            completion_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
        );

        #[cfg(all(feature = "NSError", feature = "block2"))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[unsafe(method(receiveMessageWithCompletionHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn receiveMessageWithCompletionHandler(
            &self,
            completion_handler: &block2::DynBlock<
                dyn Fn(*mut NSURLSessionWebSocketMessage, *mut NSError),
            >,
        );

        #[cfg(all(feature = "NSError", feature = "block2"))]
        /// # Safety
        ///
        /// `pong_receive_handler` block must be sendable.
        #[unsafe(method(sendPingWithPongReceiveHandler:))]
        #[unsafe(method_family = none)]
        pub unsafe fn sendPingWithPongReceiveHandler(
            &self,
            pong_receive_handler: &block2::DynBlock<dyn Fn(*mut NSError)>,
        );

        #[cfg(feature = "NSData")]
        #[unsafe(method(cancelWithCloseCode:reason:))]
        #[unsafe(method_family = none)]
        pub fn cancelWithCloseCode_reason(
            &self,
            close_code: NSURLSessionWebSocketCloseCode,
            reason: Option<&NSData>,
        );

        #[unsafe(method(maximumMessageSize))]
        #[unsafe(method_family = none)]
        pub fn maximumMessageSize(&self) -> NSInteger;

        /// Setter for [`maximumMessageSize`][Self::maximumMessageSize].
        #[unsafe(method(setMaximumMessageSize:))]
        #[unsafe(method_family = none)]
        pub fn setMaximumMessageSize(&self, maximum_message_size: NSInteger);

        #[unsafe(method(closeCode))]
        #[unsafe(method_family = none)]
        pub fn closeCode(&self) -> NSURLSessionWebSocketCloseCode;

        #[cfg(feature = "NSData")]
        #[unsafe(method(closeReason))]
        #[unsafe(method_family = none)]
        pub fn closeReason(&self) -> Option<Retained<NSData>>;

        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;
    );
}

/// The NSURLSessionMultipathServiceType enum defines constants that
/// can be used to specify the multipath service type to associate an NSURLSession.  The
/// multipath service type determines whether multipath TCP should be attempted and the conditions
/// for creating and switching between subflows.  Using these service types requires the appropriate entitlement.  Any connection attempt will fail if the process does not have the required entitlement.
/// A primary interface is a generally less expensive interface in terms of both cost and power (such as WiFi or ethernet).  A secondary interface is more expensive (such as 3G or LTE).
///
///
/// This is the default value.  No entitlement is required to set this value.
///
///
/// when the primary subflow is not performing adequately.   Requires the com.apple.developer.networking.multipath entitlement.
///
///
/// primary subflow is not performing adequately (packet loss, high round trip times, bandwidth issues).  The secondary
/// subflow will be created more aggressively than with NSURLSessionMultipathServiceTypeHandover.  Requires the com.apple.developer.networking.multipath entitlement.
///
///
/// used for better bandwidth.  This mode is only available for experimentation on devices configured for development use.
/// It can be enabled in the Developer section of the Settings app.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessionmultipathservicetype?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSURLSessionMultipathServiceType(pub NSInteger);
impl NSURLSessionMultipathServiceType {
    #[doc(alias = "NSURLSessionMultipathServiceTypeNone")]
    pub const None: Self = Self(0);
    #[doc(alias = "NSURLSessionMultipathServiceTypeHandover")]
    pub const Handover: Self = Self(1);
    #[doc(alias = "NSURLSessionMultipathServiceTypeInteractive")]
    pub const Interactive: Self = Self(2);
    #[doc(alias = "NSURLSessionMultipathServiceTypeAggregate")]
    pub const Aggregate: Self = Self(3);
}

unsafe impl Encode for NSURLSessionMultipathServiceType {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for NSURLSessionMultipathServiceType {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessionconfiguration?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct NSURLSessionConfiguration;
);

unsafe impl Send for NSURLSessionConfiguration {}

unsafe impl Sync for NSURLSessionConfiguration {}

#[cfg(feature = "NSObject")]
extern_conformance!(
    unsafe impl NSCopying for NSURLSessionConfiguration {}
);

#[cfg(feature = "NSObject")]
unsafe impl CopyingHelper for NSURLSessionConfiguration {
    type Result = Self;
}

extern_conformance!(
    unsafe impl NSObjectProtocol for NSURLSessionConfiguration {}
);

impl NSURLSessionConfiguration {
    extern_methods!(
        #[unsafe(method(defaultSessionConfiguration))]
        #[unsafe(method_family = none)]
        pub fn defaultSessionConfiguration() -> Retained<NSURLSessionConfiguration>;

        #[unsafe(method(ephemeralSessionConfiguration))]
        #[unsafe(method_family = none)]
        pub fn ephemeralSessionConfiguration() -> Retained<NSURLSessionConfiguration>;

        #[cfg(feature = "NSString")]
        #[unsafe(method(backgroundSessionConfigurationWithIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn backgroundSessionConfigurationWithIdentifier(
            identifier: &NSString,
        ) -> Retained<NSURLSessionConfiguration>;

        #[cfg(feature = "NSString")]
        #[unsafe(method(identifier))]
        #[unsafe(method_family = none)]
        pub fn identifier(&self) -> Option<Retained<NSString>>;

        #[cfg(feature = "NSURLRequest")]
        #[unsafe(method(requestCachePolicy))]
        #[unsafe(method_family = none)]
        pub fn requestCachePolicy(&self) -> NSURLRequestCachePolicy;

        #[cfg(feature = "NSURLRequest")]
        /// Setter for [`requestCachePolicy`][Self::requestCachePolicy].
        #[unsafe(method(setRequestCachePolicy:))]
        #[unsafe(method_family = none)]
        pub fn setRequestCachePolicy(&self, request_cache_policy: NSURLRequestCachePolicy);

        #[cfg(feature = "NSDate")]
        #[unsafe(method(timeoutIntervalForRequest))]
        #[unsafe(method_family = none)]
        pub fn timeoutIntervalForRequest(&self) -> NSTimeInterval;

        #[cfg(feature = "NSDate")]
        /// Setter for [`timeoutIntervalForRequest`][Self::timeoutIntervalForRequest].
        #[unsafe(method(setTimeoutIntervalForRequest:))]
        #[unsafe(method_family = none)]
        pub fn setTimeoutIntervalForRequest(&self, timeout_interval_for_request: NSTimeInterval);

        #[cfg(feature = "NSDate")]
        #[unsafe(method(timeoutIntervalForResource))]
        #[unsafe(method_family = none)]
        pub fn timeoutIntervalForResource(&self) -> NSTimeInterval;

        #[cfg(feature = "NSDate")]
        /// Setter for [`timeoutIntervalForResource`][Self::timeoutIntervalForResource].
        #[unsafe(method(setTimeoutIntervalForResource:))]
        #[unsafe(method_family = none)]
        pub fn setTimeoutIntervalForResource(&self, timeout_interval_for_resource: NSTimeInterval);

        #[cfg(feature = "NSURLRequest")]
        #[unsafe(method(networkServiceType))]
        #[unsafe(method_family = none)]
        pub fn networkServiceType(&self) -> NSURLRequestNetworkServiceType;

        #[cfg(feature = "NSURLRequest")]
        /// Setter for [`networkServiceType`][Self::networkServiceType].
        #[unsafe(method(setNetworkServiceType:))]
        #[unsafe(method_family = none)]
        pub fn setNetworkServiceType(&self, network_service_type: NSURLRequestNetworkServiceType);

        #[unsafe(method(allowsCellularAccess))]
        #[unsafe(method_family = none)]
        pub fn allowsCellularAccess(&self) -> bool;

        /// Setter for [`allowsCellularAccess`][Self::allowsCellularAccess].
        #[unsafe(method(setAllowsCellularAccess:))]
        #[unsafe(method_family = none)]
        pub fn setAllowsCellularAccess(&self, allows_cellular_access: bool);

        #[unsafe(method(allowsExpensiveNetworkAccess))]
        #[unsafe(method_family = none)]
        pub fn allowsExpensiveNetworkAccess(&self) -> bool;

        /// Setter for [`allowsExpensiveNetworkAccess`][Self::allowsExpensiveNetworkAccess].
        #[unsafe(method(setAllowsExpensiveNetworkAccess:))]
        #[unsafe(method_family = none)]
        pub fn setAllowsExpensiveNetworkAccess(&self, allows_expensive_network_access: bool);

        #[unsafe(method(allowsConstrainedNetworkAccess))]
        #[unsafe(method_family = none)]
        pub fn allowsConstrainedNetworkAccess(&self) -> bool;

        /// Setter for [`allowsConstrainedNetworkAccess`][Self::allowsConstrainedNetworkAccess].
        #[unsafe(method(setAllowsConstrainedNetworkAccess:))]
        #[unsafe(method_family = none)]
        pub fn setAllowsConstrainedNetworkAccess(&self, allows_constrained_network_access: bool);

        #[unsafe(method(requiresDNSSECValidation))]
        #[unsafe(method_family = none)]
        pub fn requiresDNSSECValidation(&self) -> bool;

        /// Setter for [`requiresDNSSECValidation`][Self::requiresDNSSECValidation].
        #[unsafe(method(setRequiresDNSSECValidation:))]
        #[unsafe(method_family = none)]
        pub fn setRequiresDNSSECValidation(&self, requires_dnssec_validation: bool);

        #[unsafe(method(waitsForConnectivity))]
        #[unsafe(method_family = none)]
        pub fn waitsForConnectivity(&self) -> bool;

        /// Setter for [`waitsForConnectivity`][Self::waitsForConnectivity].
        #[unsafe(method(setWaitsForConnectivity:))]
        #[unsafe(method_family = none)]
        pub fn setWaitsForConnectivity(&self, waits_for_connectivity: bool);

        #[unsafe(method(isDiscretionary))]
        #[unsafe(method_family = none)]
        pub fn isDiscretionary(&self) -> bool;

        /// Setter for [`isDiscretionary`][Self::isDiscretionary].
        #[unsafe(method(setDiscretionary:))]
        #[unsafe(method_family = none)]
        pub fn setDiscretionary(&self, discretionary: bool);

        #[cfg(feature = "NSString")]
        #[unsafe(method(sharedContainerIdentifier))]
        #[unsafe(method_family = none)]
        pub fn sharedContainerIdentifier(&self) -> Option<Retained<NSString>>;

        #[cfg(feature = "NSString")]
        /// Setter for [`sharedContainerIdentifier`][Self::sharedContainerIdentifier].
        ///
        /// This is [copied][crate::NSCopying::copy] when set.
        #[unsafe(method(setSharedContainerIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn setSharedContainerIdentifier(&self, shared_container_identifier: Option<&NSString>);

        #[unsafe(method(sessionSendsLaunchEvents))]
        #[unsafe(method_family = none)]
        pub fn sessionSendsLaunchEvents(&self) -> bool;

        /// Setter for [`sessionSendsLaunchEvents`][Self::sessionSendsLaunchEvents].
        #[unsafe(method(setSessionSendsLaunchEvents:))]
        #[unsafe(method_family = none)]
        pub fn setSessionSendsLaunchEvents(&self, session_sends_launch_events: bool);

        #[cfg(feature = "NSDictionary")]
        #[unsafe(method(connectionProxyDictionary))]
        #[unsafe(method_family = none)]
        pub fn connectionProxyDictionary(&self) -> Option<Retained<NSDictionary>>;

        #[cfg(feature = "NSDictionary")]
        /// Setter for [`connectionProxyDictionary`][Self::connectionProxyDictionary].
        ///
        /// This is [copied][crate::NSCopying::copy] when set.
        ///
        /// # Safety
        ///
        /// `connection_proxy_dictionary` generic should be of the correct type.
        #[unsafe(method(setConnectionProxyDictionary:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setConnectionProxyDictionary(
            &self,
            connection_proxy_dictionary: Option<&NSDictionary>,
        );

        #[deprecated = "Only supported in the classic loader, please adopt HTTP/2 and HTTP/3 instead"]
        #[unsafe(method(HTTPShouldUsePipelining))]
        #[unsafe(method_family = none)]
        pub fn HTTPShouldUsePipelining(&self) -> bool;

        /// Setter for [`HTTPShouldUsePipelining`][Self::HTTPShouldUsePipelining].
        #[deprecated = "Only supported in the classic loader, please adopt HTTP/2 and HTTP/3 instead"]
        #[unsafe(method(setHTTPShouldUsePipelining:))]
        #[unsafe(method_family = none)]
        pub fn setHTTPShouldUsePipelining(&self, http_should_use_pipelining: bool);

        #[unsafe(method(HTTPShouldSetCookies))]
        #[unsafe(method_family = none)]
        pub fn HTTPShouldSetCookies(&self) -> bool;

        /// Setter for [`HTTPShouldSetCookies`][Self::HTTPShouldSetCookies].
        #[unsafe(method(setHTTPShouldSetCookies:))]
        #[unsafe(method_family = none)]
        pub fn setHTTPShouldSetCookies(&self, http_should_set_cookies: bool);

        #[cfg(feature = "NSHTTPCookieStorage")]
        #[unsafe(method(HTTPCookieAcceptPolicy))]
        #[unsafe(method_family = none)]
        pub fn HTTPCookieAcceptPolicy(&self) -> NSHTTPCookieAcceptPolicy;

        #[cfg(feature = "NSHTTPCookieStorage")]
        /// Setter for [`HTTPCookieAcceptPolicy`][Self::HTTPCookieAcceptPolicy].
        #[unsafe(method(setHTTPCookieAcceptPolicy:))]
        #[unsafe(method_family = none)]
        pub fn setHTTPCookieAcceptPolicy(
            &self,
            http_cookie_accept_policy: NSHTTPCookieAcceptPolicy,
        );

        #[cfg(feature = "NSDictionary")]
        #[unsafe(method(HTTPAdditionalHeaders))]
        #[unsafe(method_family = none)]
        pub fn HTTPAdditionalHeaders(&self) -> Option<Retained<NSDictionary>>;

        #[cfg(feature = "NSDictionary")]
        /// Setter for [`HTTPAdditionalHeaders`][Self::HTTPAdditionalHeaders].
        ///
        /// This is [copied][crate::NSCopying::copy] when set.
        ///
        /// # Safety
        ///
        /// `http_additional_headers` generic should be of the correct type.
        #[unsafe(method(setHTTPAdditionalHeaders:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setHTTPAdditionalHeaders(
            &self,
            http_additional_headers: Option<&NSDictionary>,
        );

        #[unsafe(method(HTTPMaximumConnectionsPerHost))]
        #[unsafe(method_family = none)]
        pub fn HTTPMaximumConnectionsPerHost(&self) -> NSInteger;

        /// Setter for [`HTTPMaximumConnectionsPerHost`][Self::HTTPMaximumConnectionsPerHost].
        #[unsafe(method(setHTTPMaximumConnectionsPerHost:))]
        #[unsafe(method_family = none)]
        pub fn setHTTPMaximumConnectionsPerHost(
            &self,
            http_maximum_connections_per_host: NSInteger,
        );

        #[cfg(feature = "NSHTTPCookieStorage")]
        #[unsafe(method(HTTPCookieStorage))]
        #[unsafe(method_family = none)]
        pub fn HTTPCookieStorage(&self) -> Option<Retained<NSHTTPCookieStorage>>;

        #[cfg(feature = "NSHTTPCookieStorage")]
        /// Setter for [`HTTPCookieStorage`][Self::HTTPCookieStorage].
        #[unsafe(method(setHTTPCookieStorage:))]
        #[unsafe(method_family = none)]
        pub fn setHTTPCookieStorage(&self, http_cookie_storage: Option<&NSHTTPCookieStorage>);

        #[cfg(feature = "NSURLCredentialStorage")]
        #[unsafe(method(URLCredentialStorage))]
        #[unsafe(method_family = none)]
        pub fn URLCredentialStorage(&self) -> Option<Retained<NSURLCredentialStorage>>;

        #[cfg(feature = "NSURLCredentialStorage")]
        /// Setter for [`URLCredentialStorage`][Self::URLCredentialStorage].
        #[unsafe(method(setURLCredentialStorage:))]
        #[unsafe(method_family = none)]
        pub fn setURLCredentialStorage(
            &self,
            url_credential_storage: Option<&NSURLCredentialStorage>,
        );

        #[cfg(feature = "NSURLCache")]
        #[unsafe(method(URLCache))]
        #[unsafe(method_family = none)]
        pub fn URLCache(&self) -> Option<Retained<NSURLCache>>;

        #[cfg(feature = "NSURLCache")]
        /// Setter for [`URLCache`][Self::URLCache].
        #[unsafe(method(setURLCache:))]
        #[unsafe(method_family = none)]
        pub fn setURLCache(&self, url_cache: Option<&NSURLCache>);

        #[deprecated = "Not supported"]
        #[unsafe(method(shouldUseExtendedBackgroundIdleMode))]
        #[unsafe(method_family = none)]
        pub fn shouldUseExtendedBackgroundIdleMode(&self) -> bool;

        /// Setter for [`shouldUseExtendedBackgroundIdleMode`][Self::shouldUseExtendedBackgroundIdleMode].
        #[deprecated = "Not supported"]
        #[unsafe(method(setShouldUseExtendedBackgroundIdleMode:))]
        #[unsafe(method_family = none)]
        pub fn setShouldUseExtendedBackgroundIdleMode(
            &self,
            should_use_extended_background_idle_mode: bool,
        );

        #[cfg(feature = "NSArray")]
        #[unsafe(method(protocolClasses))]
        #[unsafe(method_family = none)]
        pub fn protocolClasses(&self) -> Option<Retained<NSArray<AnyClass>>>;

        #[cfg(feature = "NSArray")]
        /// Setter for [`protocolClasses`][Self::protocolClasses].
        ///
        /// This is [copied][crate::NSCopying::copy] when set.
        ///
        /// # Safety
        ///
        /// `protocol_classes` generic probably has further requirements.
        #[unsafe(method(setProtocolClasses:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setProtocolClasses(&self, protocol_classes: Option<&NSArray<AnyClass>>);

        #[unsafe(method(multipathServiceType))]
        #[unsafe(method_family = none)]
        pub fn multipathServiceType(&self) -> NSURLSessionMultipathServiceType;

        /// Setter for [`multipathServiceType`][Self::multipathServiceType].
        #[unsafe(method(setMultipathServiceType:))]
        #[unsafe(method_family = none)]
        pub fn setMultipathServiceType(
            &self,
            multipath_service_type: NSURLSessionMultipathServiceType,
        );

        #[unsafe(method(usesClassicLoadingMode))]
        #[unsafe(method_family = none)]
        pub fn usesClassicLoadingMode(&self) -> bool;

        /// Setter for [`usesClassicLoadingMode`][Self::usesClassicLoadingMode].
        #[unsafe(method(setUsesClassicLoadingMode:))]
        #[unsafe(method_family = none)]
        pub fn setUsesClassicLoadingMode(&self, uses_classic_loading_mode: bool);

        #[unsafe(method(enablesEarlyData))]
        #[unsafe(method_family = none)]
        pub fn enablesEarlyData(&self) -> bool;

        /// Setter for [`enablesEarlyData`][Self::enablesEarlyData].
        #[unsafe(method(setEnablesEarlyData:))]
        #[unsafe(method_family = none)]
        pub fn setEnablesEarlyData(&self, enables_early_data: bool);

        #[deprecated = "Please use NSURLSessionConfiguration.defaultSessionConfiguration or other class methods to create instances"]
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;

        #[deprecated = "Please use NSURLSessionConfiguration.defaultSessionConfiguration or other class methods to create instances"]
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new() -> Retained<Self>;
    );
}

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessiondelayedrequestdisposition?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSURLSessionDelayedRequestDisposition(pub NSInteger);
impl NSURLSessionDelayedRequestDisposition {
    #[doc(alias = "NSURLSessionDelayedRequestContinueLoading")]
    pub const ContinueLoading: Self = Self(0);
    #[doc(alias = "NSURLSessionDelayedRequestUseNewRequest")]
    pub const UseNewRequest: Self = Self(1);
    #[doc(alias = "NSURLSessionDelayedRequestCancel")]
    pub const Cancel: Self = Self(2);
}

unsafe impl Encode for NSURLSessionDelayedRequestDisposition {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for NSURLSessionDelayedRequestDisposition {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessionauthchallengedisposition?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSURLSessionAuthChallengeDisposition(pub NSInteger);
impl NSURLSessionAuthChallengeDisposition {
    #[doc(alias = "NSURLSessionAuthChallengeUseCredential")]
    pub const UseCredential: Self = Self(0);
    #[doc(alias = "NSURLSessionAuthChallengePerformDefaultHandling")]
    pub const PerformDefaultHandling: Self = Self(1);
    #[doc(alias = "NSURLSessionAuthChallengeCancelAuthenticationChallenge")]
    pub const CancelAuthenticationChallenge: Self = Self(2);
    #[doc(alias = "NSURLSessionAuthChallengeRejectProtectionSpace")]
    pub const RejectProtectionSpace: Self = Self(3);
}

unsafe impl Encode for NSURLSessionAuthChallengeDisposition {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for NSURLSessionAuthChallengeDisposition {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessionresponsedisposition?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSURLSessionResponseDisposition(pub NSInteger);
impl NSURLSessionResponseDisposition {
    #[doc(alias = "NSURLSessionResponseCancel")]
    pub const Cancel: Self = Self(0);
    #[doc(alias = "NSURLSessionResponseAllow")]
    pub const Allow: Self = Self(1);
    #[doc(alias = "NSURLSessionResponseBecomeDownload")]
    pub const BecomeDownload: Self = Self(2);
    #[doc(alias = "NSURLSessionResponseBecomeStream")]
    pub const BecomeStream: Self = Self(3);
}

unsafe impl Encode for NSURLSessionResponseDisposition {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for NSURLSessionResponseDisposition {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessiondelegate?language=objc)
    pub unsafe trait NSURLSessionDelegate: NSObjectProtocol + Send + Sync {
        #[cfg(feature = "NSError")]
        #[optional]
        #[unsafe(method(URLSession:didBecomeInvalidWithError:))]
        #[unsafe(method_family = none)]
        fn URLSession_didBecomeInvalidWithError(
            &self,
            session: &NSURLSession,
            error: Option<&NSError>,
        );

        #[cfg(all(
            feature = "NSURLAuthenticationChallenge",
            feature = "NSURLCredential",
            feature = "block2"
        ))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[optional]
        #[unsafe(method(URLSession:didReceiveChallenge:completionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn URLSession_didReceiveChallenge_completionHandler(
            &self,
            session: &NSURLSession,
            challenge: &NSURLAuthenticationChallenge,
            completion_handler: &block2::DynBlock<
                dyn Fn(NSURLSessionAuthChallengeDisposition, *mut NSURLCredential),
            >,
        );

        #[optional]
        #[unsafe(method(URLSessionDidFinishEventsForBackgroundURLSession:))]
        #[unsafe(method_family = none)]
        fn URLSessionDidFinishEventsForBackgroundURLSession(&self, session: &NSURLSession);
    }
);

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessiontaskdelegate?language=objc)
    pub unsafe trait NSURLSessionTaskDelegate: NSURLSessionDelegate {
        #[optional]
        #[unsafe(method(URLSession:didCreateTask:))]
        #[unsafe(method_family = none)]
        fn URLSession_didCreateTask(&self, session: &NSURLSession, task: &NSURLSessionTask);

        #[cfg(all(feature = "NSURLRequest", feature = "block2"))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[optional]
        #[unsafe(method(URLSession:task:willBeginDelayedRequest:completionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn URLSession_task_willBeginDelayedRequest_completionHandler(
            &self,
            session: &NSURLSession,
            task: &NSURLSessionTask,
            request: &NSURLRequest,
            completion_handler: &block2::DynBlock<
                dyn Fn(NSURLSessionDelayedRequestDisposition, *mut NSURLRequest),
            >,
        );

        #[optional]
        #[unsafe(method(URLSession:taskIsWaitingForConnectivity:))]
        #[unsafe(method_family = none)]
        fn URLSession_taskIsWaitingForConnectivity(
            &self,
            session: &NSURLSession,
            task: &NSURLSessionTask,
        );

        #[cfg(all(
            feature = "NSURLRequest",
            feature = "NSURLResponse",
            feature = "block2"
        ))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[optional]
        #[unsafe(method(URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn URLSession_task_willPerformHTTPRedirection_newRequest_completionHandler(
            &self,
            session: &NSURLSession,
            task: &NSURLSessionTask,
            response: &NSHTTPURLResponse,
            request: &NSURLRequest,
            completion_handler: &block2::DynBlock<dyn Fn(*mut NSURLRequest)>,
        );

        #[cfg(all(
            feature = "NSURLAuthenticationChallenge",
            feature = "NSURLCredential",
            feature = "block2"
        ))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[optional]
        #[unsafe(method(URLSession:task:didReceiveChallenge:completionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn URLSession_task_didReceiveChallenge_completionHandler(
            &self,
            session: &NSURLSession,
            task: &NSURLSessionTask,
            challenge: &NSURLAuthenticationChallenge,
            completion_handler: &block2::DynBlock<
                dyn Fn(NSURLSessionAuthChallengeDisposition, *mut NSURLCredential),
            >,
        );

        #[cfg(all(feature = "NSStream", feature = "block2"))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[optional]
        #[unsafe(method(URLSession:task:needNewBodyStream:))]
        #[unsafe(method_family = none)]
        unsafe fn URLSession_task_needNewBodyStream(
            &self,
            session: &NSURLSession,
            task: &NSURLSessionTask,
            completion_handler: &block2::DynBlock<dyn Fn(*mut NSInputStream)>,
        );

        #[cfg(all(feature = "NSStream", feature = "block2"))]
        /// Tells the delegate if a task requires a new body stream starting from the given offset. This may be
        /// necessary when resuming a failed upload task.
        ///
        /// - Parameter session: The session containing the task that needs a new body stream from the given offset.
        /// - Parameter task: The task that needs a new body stream.
        /// - Parameter offset: The starting offset required for the body stream.
        /// - Parameter completionHandler: A completion handler that your delegate method should call with the new body stream.
        ///
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[optional]
        #[unsafe(method(URLSession:task:needNewBodyStreamFromOffset:completionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn URLSession_task_needNewBodyStreamFromOffset_completionHandler(
            &self,
            session: &NSURLSession,
            task: &NSURLSessionTask,
            offset: i64,
            completion_handler: &block2::DynBlock<dyn Fn(*mut NSInputStream)>,
        );

        #[optional]
        #[unsafe(method(URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:))]
        #[unsafe(method_family = none)]
        fn URLSession_task_didSendBodyData_totalBytesSent_totalBytesExpectedToSend(
            &self,
            session: &NSURLSession,
            task: &NSURLSessionTask,
            bytes_sent: i64,
            total_bytes_sent: i64,
            total_bytes_expected_to_send: i64,
        );

        #[cfg(feature = "NSURLResponse")]
        #[optional]
        #[unsafe(method(URLSession:task:didReceiveInformationalResponse:))]
        #[unsafe(method_family = none)]
        fn URLSession_task_didReceiveInformationalResponse(
            &self,
            session: &NSURLSession,
            task: &NSURLSessionTask,
            response: &NSHTTPURLResponse,
        );

        #[optional]
        #[unsafe(method(URLSession:task:didFinishCollectingMetrics:))]
        #[unsafe(method_family = none)]
        fn URLSession_task_didFinishCollectingMetrics(
            &self,
            session: &NSURLSession,
            task: &NSURLSessionTask,
            metrics: &NSURLSessionTaskMetrics,
        );

        #[cfg(feature = "NSError")]
        #[optional]
        #[unsafe(method(URLSession:task:didCompleteWithError:))]
        #[unsafe(method_family = none)]
        fn URLSession_task_didCompleteWithError(
            &self,
            session: &NSURLSession,
            task: &NSURLSessionTask,
            error: Option<&NSError>,
        );
    }
);

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessiondatadelegate?language=objc)
    pub unsafe trait NSURLSessionDataDelegate: NSURLSessionTaskDelegate {
        #[cfg(all(feature = "NSURLResponse", feature = "block2"))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[optional]
        #[unsafe(method(URLSession:dataTask:didReceiveResponse:completionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn URLSession_dataTask_didReceiveResponse_completionHandler(
            &self,
            session: &NSURLSession,
            data_task: &NSURLSessionDataTask,
            response: &NSURLResponse,
            completion_handler: &block2::DynBlock<dyn Fn(NSURLSessionResponseDisposition)>,
        );

        #[optional]
        #[unsafe(method(URLSession:dataTask:didBecomeDownloadTask:))]
        #[unsafe(method_family = none)]
        fn URLSession_dataTask_didBecomeDownloadTask(
            &self,
            session: &NSURLSession,
            data_task: &NSURLSessionDataTask,
            download_task: &NSURLSessionDownloadTask,
        );

        #[optional]
        #[unsafe(method(URLSession:dataTask:didBecomeStreamTask:))]
        #[unsafe(method_family = none)]
        fn URLSession_dataTask_didBecomeStreamTask(
            &self,
            session: &NSURLSession,
            data_task: &NSURLSessionDataTask,
            stream_task: &NSURLSessionStreamTask,
        );

        #[cfg(feature = "NSData")]
        #[optional]
        #[unsafe(method(URLSession:dataTask:didReceiveData:))]
        #[unsafe(method_family = none)]
        fn URLSession_dataTask_didReceiveData(
            &self,
            session: &NSURLSession,
            data_task: &NSURLSessionDataTask,
            data: &NSData,
        );

        #[cfg(all(feature = "NSURLCache", feature = "block2"))]
        /// # Safety
        ///
        /// `completion_handler` block must be sendable.
        #[optional]
        #[unsafe(method(URLSession:dataTask:willCacheResponse:completionHandler:))]
        #[unsafe(method_family = none)]
        unsafe fn URLSession_dataTask_willCacheResponse_completionHandler(
            &self,
            session: &NSURLSession,
            data_task: &NSURLSessionDataTask,
            proposed_response: &NSCachedURLResponse,
            completion_handler: &block2::DynBlock<dyn Fn(*mut NSCachedURLResponse)>,
        );
    }
);

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessiondownloaddelegate?language=objc)
    pub unsafe trait NSURLSessionDownloadDelegate: NSURLSessionTaskDelegate {
        #[cfg(feature = "NSURL")]
        #[unsafe(method(URLSession:downloadTask:didFinishDownloadingToURL:))]
        #[unsafe(method_family = none)]
        fn URLSession_downloadTask_didFinishDownloadingToURL(
            &self,
            session: &NSURLSession,
            download_task: &NSURLSessionDownloadTask,
            location: &NSURL,
        );

        #[optional]
        #[unsafe(method(URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:))]
        #[unsafe(method_family = none)]
        fn URLSession_downloadTask_didWriteData_totalBytesWritten_totalBytesExpectedToWrite(
            &self,
            session: &NSURLSession,
            download_task: &NSURLSessionDownloadTask,
            bytes_written: i64,
            total_bytes_written: i64,
            total_bytes_expected_to_write: i64,
        );

        #[optional]
        #[unsafe(method(URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:))]
        #[unsafe(method_family = none)]
        fn URLSession_downloadTask_didResumeAtOffset_expectedTotalBytes(
            &self,
            session: &NSURLSession,
            download_task: &NSURLSessionDownloadTask,
            file_offset: i64,
            expected_total_bytes: i64,
        );
    }
);

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessionstreamdelegate?language=objc)
    pub unsafe trait NSURLSessionStreamDelegate: NSURLSessionTaskDelegate {
        #[optional]
        #[unsafe(method(URLSession:readClosedForStreamTask:))]
        #[unsafe(method_family = none)]
        fn URLSession_readClosedForStreamTask(
            &self,
            session: &NSURLSession,
            stream_task: &NSURLSessionStreamTask,
        );

        #[optional]
        #[unsafe(method(URLSession:writeClosedForStreamTask:))]
        #[unsafe(method_family = none)]
        fn URLSession_writeClosedForStreamTask(
            &self,
            session: &NSURLSession,
            stream_task: &NSURLSessionStreamTask,
        );

        #[optional]
        #[unsafe(method(URLSession:betterRouteDiscoveredForStreamTask:))]
        #[unsafe(method_family = none)]
        fn URLSession_betterRouteDiscoveredForStreamTask(
            &self,
            session: &NSURLSession,
            stream_task: &NSURLSessionStreamTask,
        );

        #[cfg(feature = "NSStream")]
        #[optional]
        #[unsafe(method(URLSession:streamTask:didBecomeInputStream:outputStream:))]
        #[unsafe(method_family = none)]
        fn URLSession_streamTask_didBecomeInputStream_outputStream(
            &self,
            session: &NSURLSession,
            stream_task: &NSURLSessionStreamTask,
            input_stream: &NSInputStream,
            output_stream: &NSOutputStream,
        );
    }
);

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessionwebsocketdelegate?language=objc)
    pub unsafe trait NSURLSessionWebSocketDelegate: NSURLSessionTaskDelegate {
        #[cfg(feature = "NSString")]
        #[optional]
        #[unsafe(method(URLSession:webSocketTask:didOpenWithProtocol:))]
        #[unsafe(method_family = none)]
        fn URLSession_webSocketTask_didOpenWithProtocol(
            &self,
            session: &NSURLSession,
            web_socket_task: &NSURLSessionWebSocketTask,
            protocol: Option<&NSString>,
        );

        #[cfg(feature = "NSData")]
        #[optional]
        #[unsafe(method(URLSession:webSocketTask:didCloseWithCode:reason:))]
        #[unsafe(method_family = none)]
        fn URLSession_webSocketTask_didCloseWithCode_reason(
            &self,
            session: &NSURLSession,
            web_socket_task: &NSURLSessionWebSocketTask,
            close_code: NSURLSessionWebSocketCloseCode,
            reason: Option<&NSData>,
        );
    }
);

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessiondownloadtaskresumedata?language=objc)
    #[cfg(feature = "NSString")]
    pub static NSURLSessionDownloadTaskResumeData: &'static NSString;
}

extern "C" {
    /// Key in the userInfo dictionary of an NSError received during a failed upload.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessionuploadtaskresumedata?language=objc)
    #[cfg(feature = "NSString")]
    pub static NSURLSessionUploadTaskResumeData: &'static NSString;
}

/// NSURLSessionDeprecated.
impl NSURLSessionConfiguration {
    extern_methods!(
        #[cfg(feature = "NSString")]
        #[deprecated]
        #[unsafe(method(backgroundSessionConfiguration:))]
        #[unsafe(method_family = none)]
        pub fn backgroundSessionConfiguration(
            identifier: &NSString,
        ) -> Retained<NSURLSessionConfiguration>;
    );
}

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessiontaskmetricsresourcefetchtype?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSURLSessionTaskMetricsResourceFetchType(pub NSInteger);
impl NSURLSessionTaskMetricsResourceFetchType {
    #[doc(alias = "NSURLSessionTaskMetricsResourceFetchTypeUnknown")]
    pub const Unknown: Self = Self(0);
    #[doc(alias = "NSURLSessionTaskMetricsResourceFetchTypeNetworkLoad")]
    pub const NetworkLoad: Self = Self(1);
    #[doc(alias = "NSURLSessionTaskMetricsResourceFetchTypeServerPush")]
    #[deprecated = "Server push is no longer supported as of iOS 17 and aligned releases"]
    pub const ServerPush: Self = Self(2);
    #[doc(alias = "NSURLSessionTaskMetricsResourceFetchTypeLocalCache")]
    pub const LocalCache: Self = Self(3);
}

unsafe impl Encode for NSURLSessionTaskMetricsResourceFetchType {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for NSURLSessionTaskMetricsResourceFetchType {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessiontaskmetricsdomainresolutionprotocol?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSURLSessionTaskMetricsDomainResolutionProtocol(pub NSInteger);
impl NSURLSessionTaskMetricsDomainResolutionProtocol {
    #[doc(alias = "NSURLSessionTaskMetricsDomainResolutionProtocolUnknown")]
    pub const Unknown: Self = Self(0);
    #[doc(alias = "NSURLSessionTaskMetricsDomainResolutionProtocolUDP")]
    pub const UDP: Self = Self(1);
    #[doc(alias = "NSURLSessionTaskMetricsDomainResolutionProtocolTCP")]
    pub const TCP: Self = Self(2);
    #[doc(alias = "NSURLSessionTaskMetricsDomainResolutionProtocolTLS")]
    pub const TLS: Self = Self(3);
    #[doc(alias = "NSURLSessionTaskMetricsDomainResolutionProtocolHTTPS")]
    pub const HTTPS: Self = Self(4);
}

unsafe impl Encode for NSURLSessionTaskMetricsDomainResolutionProtocol {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for NSURLSessionTaskMetricsDomainResolutionProtocol {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessiontasktransactionmetrics?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct NSURLSessionTaskTransactionMetrics;
);

unsafe impl Send for NSURLSessionTaskTransactionMetrics {}

unsafe impl Sync for NSURLSessionTaskTransactionMetrics {}

extern_conformance!(
    unsafe impl NSObjectProtocol for NSURLSessionTaskTransactionMetrics {}
);

impl NSURLSessionTaskTransactionMetrics {
    extern_methods!(
        #[cfg(feature = "NSURLRequest")]
        #[unsafe(method(request))]
        #[unsafe(method_family = none)]
        pub fn request(&self) -> Retained<NSURLRequest>;

        #[cfg(feature = "NSURLResponse")]
        #[unsafe(method(response))]
        #[unsafe(method_family = none)]
        pub fn response(&self) -> Option<Retained<NSURLResponse>>;

        #[cfg(feature = "NSDate")]
        #[unsafe(method(fetchStartDate))]
        #[unsafe(method_family = none)]
        pub fn fetchStartDate(&self) -> Option<Retained<NSDate>>;

        #[cfg(feature = "NSDate")]
        #[unsafe(method(domainLookupStartDate))]
        #[unsafe(method_family = none)]
        pub fn domainLookupStartDate(&self) -> Option<Retained<NSDate>>;

        #[cfg(feature = "NSDate")]
        #[unsafe(method(domainLookupEndDate))]
        #[unsafe(method_family = none)]
        pub fn domainLookupEndDate(&self) -> Option<Retained<NSDate>>;

        #[cfg(feature = "NSDate")]
        #[unsafe(method(connectStartDate))]
        #[unsafe(method_family = none)]
        pub fn connectStartDate(&self) -> Option<Retained<NSDate>>;

        #[cfg(feature = "NSDate")]
        #[unsafe(method(secureConnectionStartDate))]
        #[unsafe(method_family = none)]
        pub fn secureConnectionStartDate(&self) -> Option<Retained<NSDate>>;

        #[cfg(feature = "NSDate")]
        #[unsafe(method(secureConnectionEndDate))]
        #[unsafe(method_family = none)]
        pub fn secureConnectionEndDate(&self) -> Option<Retained<NSDate>>;

        #[cfg(feature = "NSDate")]
        #[unsafe(method(connectEndDate))]
        #[unsafe(method_family = none)]
        pub fn connectEndDate(&self) -> Option<Retained<NSDate>>;

        #[cfg(feature = "NSDate")]
        #[unsafe(method(requestStartDate))]
        #[unsafe(method_family = none)]
        pub fn requestStartDate(&self) -> Option<Retained<NSDate>>;

        #[cfg(feature = "NSDate")]
        #[unsafe(method(requestEndDate))]
        #[unsafe(method_family = none)]
        pub fn requestEndDate(&self) -> Option<Retained<NSDate>>;

        #[cfg(feature = "NSDate")]
        #[unsafe(method(responseStartDate))]
        #[unsafe(method_family = none)]
        pub fn responseStartDate(&self) -> Option<Retained<NSDate>>;

        #[cfg(feature = "NSDate")]
        #[unsafe(method(responseEndDate))]
        #[unsafe(method_family = none)]
        pub fn responseEndDate(&self) -> Option<Retained<NSDate>>;

        #[cfg(feature = "NSString")]
        #[unsafe(method(networkProtocolName))]
        #[unsafe(method_family = none)]
        pub fn networkProtocolName(&self) -> Option<Retained<NSString>>;

        #[unsafe(method(isProxyConnection))]
        #[unsafe(method_family = none)]
        pub fn isProxyConnection(&self) -> bool;

        #[unsafe(method(isReusedConnection))]
        #[unsafe(method_family = none)]
        pub fn isReusedConnection(&self) -> bool;

        #[unsafe(method(resourceFetchType))]
        #[unsafe(method_family = none)]
        pub fn resourceFetchType(&self) -> NSURLSessionTaskMetricsResourceFetchType;

        #[unsafe(method(countOfRequestHeaderBytesSent))]
        #[unsafe(method_family = none)]
        pub fn countOfRequestHeaderBytesSent(&self) -> i64;

        #[unsafe(method(countOfRequestBodyBytesSent))]
        #[unsafe(method_family = none)]
        pub fn countOfRequestBodyBytesSent(&self) -> i64;

        #[unsafe(method(countOfRequestBodyBytesBeforeEncoding))]
        #[unsafe(method_family = none)]
        pub fn countOfRequestBodyBytesBeforeEncoding(&self) -> i64;

        #[unsafe(method(countOfResponseHeaderBytesReceived))]
        #[unsafe(method_family = none)]
        pub fn countOfResponseHeaderBytesReceived(&self) -> i64;

        #[unsafe(method(countOfResponseBodyBytesReceived))]
        #[unsafe(method_family = none)]
        pub fn countOfResponseBodyBytesReceived(&self) -> i64;

        #[unsafe(method(countOfResponseBodyBytesAfterDecoding))]
        #[unsafe(method_family = none)]
        pub fn countOfResponseBodyBytesAfterDecoding(&self) -> i64;

        #[cfg(feature = "NSString")]
        #[unsafe(method(localAddress))]
        #[unsafe(method_family = none)]
        pub fn localAddress(&self) -> Option<Retained<NSString>>;

        #[cfg(feature = "NSValue")]
        #[unsafe(method(localPort))]
        #[unsafe(method_family = none)]
        pub fn localPort(&self) -> Option<Retained<NSNumber>>;

        #[cfg(feature = "NSString")]
        #[unsafe(method(remoteAddress))]
        #[unsafe(method_family = none)]
        pub fn remoteAddress(&self) -> Option<Retained<NSString>>;

        #[cfg(feature = "NSValue")]
        #[unsafe(method(remotePort))]
        #[unsafe(method_family = none)]
        pub fn remotePort(&self) -> Option<Retained<NSNumber>>;

        #[cfg(feature = "NSValue")]
        #[unsafe(method(negotiatedTLSProtocolVersion))]
        #[unsafe(method_family = none)]
        pub fn negotiatedTLSProtocolVersion(&self) -> Option<Retained<NSNumber>>;

        #[cfg(feature = "NSValue")]
        #[unsafe(method(negotiatedTLSCipherSuite))]
        #[unsafe(method_family = none)]
        pub fn negotiatedTLSCipherSuite(&self) -> Option<Retained<NSNumber>>;

        #[unsafe(method(isCellular))]
        #[unsafe(method_family = none)]
        pub fn isCellular(&self) -> bool;

        #[unsafe(method(isExpensive))]
        #[unsafe(method_family = none)]
        pub fn isExpensive(&self) -> bool;

        #[unsafe(method(isConstrained))]
        #[unsafe(method_family = none)]
        pub fn isConstrained(&self) -> bool;

        #[unsafe(method(isMultipath))]
        #[unsafe(method_family = none)]
        pub fn isMultipath(&self) -> bool;

        #[unsafe(method(domainResolutionProtocol))]
        #[unsafe(method_family = none)]
        pub fn domainResolutionProtocol(&self) -> NSURLSessionTaskMetricsDomainResolutionProtocol;

        #[deprecated = "Not supported"]
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;

        #[deprecated = "Not supported"]
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new() -> Retained<Self>;
    );
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlsessiontaskmetrics?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct NSURLSessionTaskMetrics;
);

unsafe impl Send for NSURLSessionTaskMetrics {}

unsafe impl Sync for NSURLSessionTaskMetrics {}

extern_conformance!(
    unsafe impl NSObjectProtocol for NSURLSessionTaskMetrics {}
);

impl NSURLSessionTaskMetrics {
    extern_methods!(
        #[cfg(feature = "NSArray")]
        #[unsafe(method(transactionMetrics))]
        #[unsafe(method_family = none)]
        pub fn transactionMetrics(&self) -> Retained<NSArray<NSURLSessionTaskTransactionMetrics>>;

        #[cfg(feature = "NSDateInterval")]
        #[unsafe(method(taskInterval))]
        #[unsafe(method_family = none)]
        pub fn taskInterval(&self) -> Retained<NSDateInterval>;

        #[unsafe(method(redirectCount))]
        #[unsafe(method_family = none)]
        pub fn redirectCount(&self) -> NSUInteger;

        #[deprecated = "Not supported"]
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;

        #[deprecated = "Not supported"]
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new() -> Retained<Self>;
    );
}
