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

use crate::*;

/// An event that occurs during the operation of a `CKSyncEngine`.
/// See ``CKSyncEngineEvent`` for more details.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncengineeventtype?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CKSyncEngineEventType(pub NSInteger);
impl CKSyncEngineEventType {
    /// The sync engine state was updated. You should persist it locally.
    #[doc(alias = "CKSyncEngineEventTypeStateUpdate")]
    pub const StateUpdate: Self = Self(0);
    /// The user signed in or out of their account.
    #[doc(alias = "CKSyncEngineEventTypeAccountChange")]
    pub const AccountChange: Self = Self(1);
    /// The sync engine fetched new database changes from the server.
    #[doc(alias = "CKSyncEngineEventTypeFetchedDatabaseChanges")]
    pub const FetchedDatabaseChanges: Self = Self(2);
    /// The sync engine fetched new record zone changes from the server.
    #[doc(alias = "CKSyncEngineEventTypeFetchedRecordZoneChanges")]
    pub const FetchedRecordZoneChanges: Self = Self(3);
    /// The sync engine sent a batch of database changes to the server.
    #[doc(alias = "CKSyncEngineEventTypeSentDatabaseChanges")]
    pub const SentDatabaseChanges: Self = Self(4);
    /// The sync engine sent a batch of record zone changes to the server.
    #[doc(alias = "CKSyncEngineEventTypeSentRecordZoneChanges")]
    pub const SentRecordZoneChanges: Self = Self(5);
    /// The sync engine is about to fetch changes from the server.
    #[doc(alias = "CKSyncEngineEventTypeWillFetchChanges")]
    pub const WillFetchChanges: Self = Self(6);
    /// The sync engine is about to fetch record zone changes from the server for a specific zone.
    #[doc(alias = "CKSyncEngineEventTypeWillFetchRecordZoneChanges")]
    pub const WillFetchRecordZoneChanges: Self = Self(7);
    /// The sync engine finished fetching record zone changes from the server for a specific zone.
    #[doc(alias = "CKSyncEngineEventTypeDidFetchRecordZoneChanges")]
    pub const DidFetchRecordZoneChanges: Self = Self(8);
    /// The sync engine finished fetching changes from the server.
    #[doc(alias = "CKSyncEngineEventTypeDidFetchChanges")]
    pub const DidFetchChanges: Self = Self(9);
    /// The sync engine is about to send changes to the server.
    #[doc(alias = "CKSyncEngineEventTypeWillSendChanges")]
    pub const WillSendChanges: Self = Self(10);
    /// The sync engine finished sending changes to the server.
    #[doc(alias = "CKSyncEngineEventTypeDidSendChanges")]
    pub const DidSendChanges: Self = Self(11);
}

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

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

extern_class!(
    /// An event that occurs during the operation of a `CKSyncEngine`.
    ///
    /// While syncing, `CKSyncEngine` posts several different types of events.
    /// Each event has an associated struct value with details describing the nature of the event.
    ///
    /// At a high level, the sync engine events can be grouped into a few different categories:
    ///
    /// ## Local state changes
    ///
    /// - ``CKSyncEngineStateUpdateEvent``
    /// - ``CKSyncEngineAccountChangeEvent``
    ///
    /// ## Fetched changes
    ///
    /// - ``CKSyncEngineFetchedDatabaseChangesEvent``
    /// - ``CKSyncEngineFetchedRecordZoneChangesEvent``
    ///
    /// ## Sent changes
    ///
    /// - ``CKSyncEngineSentDatabaseChangesEvent``
    /// - ``CKSyncEngineSentRecordZoneChangesEvent``
    ///
    /// ## Fetch changes lifecycle
    ///
    /// - ``CKSyncEngineWillFetchChangesEvent``
    /// - ``CKSyncEngineWillFetchRecordZoneChangesEvent``
    /// - ``CKSyncEngineDidFetchRecordZoneChangesEvent``
    /// - ``CKSyncEngineDidFetchChangesEvent``
    ///
    /// ## Send changes lifecycle
    ///
    /// - ``CKSyncEngineWillSendChangesEvent``
    /// - ``CKSyncEngineDidSendChangesEvent``
    ///
    /// See the documentation for each event struct for more details about when and why an event might be posted.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncengineevent?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEngineEvent;
);

unsafe impl Send for CKSyncEngineEvent {}

unsafe impl Sync for CKSyncEngineEvent {}

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

impl CKSyncEngineEvent {
    extern_methods!(
        #[unsafe(method(type))]
        #[unsafe(method_family = none)]
        pub unsafe fn r#type(&self) -> CKSyncEngineEventType;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(stateUpdateEvent))]
        #[unsafe(method_family = none)]
        pub unsafe fn stateUpdateEvent(&self) -> Retained<CKSyncEngineStateUpdateEvent>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(accountChangeEvent))]
        #[unsafe(method_family = none)]
        pub unsafe fn accountChangeEvent(&self) -> Retained<CKSyncEngineAccountChangeEvent>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(willFetchChangesEvent))]
        #[unsafe(method_family = none)]
        pub unsafe fn willFetchChangesEvent(&self) -> Retained<CKSyncEngineWillFetchChangesEvent>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(fetchedDatabaseChangesEvent))]
        #[unsafe(method_family = none)]
        pub unsafe fn fetchedDatabaseChangesEvent(
            &self,
        ) -> Retained<CKSyncEngineFetchedDatabaseChangesEvent>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(didFetchChangesEvent))]
        #[unsafe(method_family = none)]
        pub unsafe fn didFetchChangesEvent(&self) -> Retained<CKSyncEngineDidFetchChangesEvent>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(willFetchRecordZoneChangesEvent))]
        #[unsafe(method_family = none)]
        pub unsafe fn willFetchRecordZoneChangesEvent(
            &self,
        ) -> Retained<CKSyncEngineWillFetchRecordZoneChangesEvent>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(fetchedRecordZoneChangesEvent))]
        #[unsafe(method_family = none)]
        pub unsafe fn fetchedRecordZoneChangesEvent(
            &self,
        ) -> Retained<CKSyncEngineFetchedRecordZoneChangesEvent>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(didFetchRecordZoneChangesEvent))]
        #[unsafe(method_family = none)]
        pub unsafe fn didFetchRecordZoneChangesEvent(
            &self,
        ) -> Retained<CKSyncEngineDidFetchRecordZoneChangesEvent>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(willSendChangesEvent))]
        #[unsafe(method_family = none)]
        pub unsafe fn willSendChangesEvent(&self) -> Retained<CKSyncEngineWillSendChangesEvent>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(sentDatabaseChangesEvent))]
        #[unsafe(method_family = none)]
        pub unsafe fn sentDatabaseChangesEvent(
            &self,
        ) -> Retained<CKSyncEngineSentDatabaseChangesEvent>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(sentRecordZoneChangesEvent))]
        #[unsafe(method_family = none)]
        pub unsafe fn sentRecordZoneChangesEvent(
            &self,
        ) -> Retained<CKSyncEngineSentRecordZoneChangesEvent>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(didSendChangesEvent))]
        #[unsafe(method_family = none)]
        pub unsafe fn didSendChangesEvent(&self) -> Retained<CKSyncEngineDidSendChangesEvent>;

        #[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>;
    );
}

extern_class!(
    /// The sync engine state was updated, and you should persist it locally.
    ///
    /// In order to function properly and efficiently, `CKSyncEngine` tracks some state internally.
    /// When the sync engine state changes, it will give you the latest serialized version in a ``CKSyncEngine/Event/StateUpdate``.
    /// This event will happen occasionally when the sync engine modifies the state internally during normal sync operation.
    /// This event will also happen when you change the state yourself.
    ///
    /// The sync engine does not persist this state to disk, so you need to persist it in alongside your own local data.
    /// The next time your process launches, use this latest state serialization in ``CKSyncEngineConfiguration/stateSerialization`` to initialize your sync engine.
    ///
    /// This state is directly tied to the changes you fetch and send with the sync engine.
    /// You should ensure that any changes fetched prior to receiving this state are also persisted alongside this state.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginestateupdateevent?language=objc)
    #[unsafe(super(CKSyncEngineEvent, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEngineStateUpdateEvent;
);

unsafe impl Send for CKSyncEngineStateUpdateEvent {}

unsafe impl Sync for CKSyncEngineStateUpdateEvent {}

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

impl CKSyncEngineStateUpdateEvent {
    extern_methods!(
        #[cfg(feature = "CKSyncEngineState")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(stateSerialization))]
        #[unsafe(method_family = none)]
        pub unsafe fn stateSerialization(&self) -> Retained<CKSyncEngineStateSerialization>;
    );
}

/// Methods declared on superclass `CKSyncEngineEvent`.
impl CKSyncEngineStateUpdateEvent {
    extern_methods!(
        #[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/cloudkit/cksyncengineaccountchangetype?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CKSyncEngineAccountChangeType(pub NSInteger);
impl CKSyncEngineAccountChangeType {
    /// The user signed in to an account.
    ///
    /// If you already have data stored locally, you have a few options:
    ///
    /// - Merge the local data with the newly-signed-in account's data.
    /// - Keep the local data separate from cloud-synced data (e.g. a separate "local account").
    /// - Delete the local data.
    /// - Prompt the user to make the decision.
    #[doc(alias = "CKSyncEngineAccountChangeTypeSignIn")]
    pub const SignIn: Self = Self(0);
    /// The user signed out of their account.
    ///
    /// You should delete any locally-stored data for the previous account.
    #[doc(alias = "CKSyncEngineAccountChangeTypeSignOut")]
    pub const SignOut: Self = Self(1);
    /// The user switched from one account to another.
    /// This might happen if the user signs out and in to a new account while your application is quit.
    ///
    /// You should delete any locally-stored data for the previous account.
    #[doc(alias = "CKSyncEngineAccountChangeTypeSwitchAccounts")]
    pub const SwitchAccounts: Self = Self(2);
}

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

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

extern_class!(
    /// The user signed in or out of their account.
    ///
    /// The sync engine automatically listens for account changes, and it will send this event when the user signs in or out.
    /// It's your responsibility to react appropriately to this change and update your local persistence.
    ///
    /// When the logged-in account changes, the sync engine will reset its internal state under the hood.
    /// This means that it will clear any pending database or record zone changes that you may have added.
    ///
    /// Note that it's possible the account changes multiple times while your app is quit.
    /// If this happens, you will only receive one account change event representing the transition between the last known state and the current state.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncengineaccountchangeevent?language=objc)
    #[unsafe(super(CKSyncEngineEvent, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEngineAccountChangeEvent;
);

unsafe impl Send for CKSyncEngineAccountChangeEvent {}

unsafe impl Sync for CKSyncEngineAccountChangeEvent {}

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

impl CKSyncEngineAccountChangeEvent {
    extern_methods!(
        /// The type of account change that occurred.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(changeType))]
        #[unsafe(method_family = none)]
        pub unsafe fn changeType(&self) -> CKSyncEngineAccountChangeType;

        #[cfg(feature = "CKRecordID")]
        /// The user record ID for the previous user.
        ///
        /// If the user just signed in, this will be `nil`.
        /// If the user signed out or switched accounts, this will be the old account.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(previousUser))]
        #[unsafe(method_family = none)]
        pub unsafe fn previousUser(&self) -> Option<Retained<CKRecordID>>;

        #[cfg(feature = "CKRecordID")]
        /// The user record ID for the current user.
        ///
        /// If the user just signed in or switched accounts, this will be the new user record ID.
        /// If the user signed out, this will be `nil`.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(currentUser))]
        #[unsafe(method_family = none)]
        pub unsafe fn currentUser(&self) -> Option<Retained<CKRecordID>>;
    );
}

/// Methods declared on superclass `CKSyncEngineEvent`.
impl CKSyncEngineAccountChangeEvent {
    extern_methods!(
        #[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>;
    );
}

extern_class!(
    /// A batch of database changes was fetched from the server.
    ///
    /// If there are a lot of new changes on the server, then you might receive many of these events in a row.
    ///
    /// The ordering of fetched changes is not guaranteed, but changes will typically be fetched from oldest to newest.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginefetcheddatabasechangesevent?language=objc)
    #[unsafe(super(CKSyncEngineEvent, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEngineFetchedDatabaseChangesEvent;
);

unsafe impl Send for CKSyncEngineFetchedDatabaseChangesEvent {}

unsafe impl Sync for CKSyncEngineFetchedDatabaseChangesEvent {}

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

impl CKSyncEngineFetchedDatabaseChangesEvent {
    extern_methods!(
        #[cfg(feature = "CKRecordZone")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(modifications))]
        #[unsafe(method_family = none)]
        pub unsafe fn modifications(&self) -> Retained<NSArray<CKRecordZone>>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(deletions))]
        #[unsafe(method_family = none)]
        pub unsafe fn deletions(&self) -> Retained<NSArray<CKSyncEngineFetchedZoneDeletion>>;
    );
}

/// Methods declared on superclass `CKSyncEngineEvent`.
impl CKSyncEngineFetchedDatabaseChangesEvent {
    extern_methods!(
        #[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>;
    );
}

extern_class!(
    /// A batch of record zone changes was fetched from the server.
    ///
    /// If there are a lot of new changes on the server, then you might receive many of these events in a row.
    ///
    /// The ordering of fetched changes is not guaranteed, but changes will typically be fetched from oldest to newest.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginefetchedrecordzonechangesevent?language=objc)
    #[unsafe(super(CKSyncEngineEvent, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEngineFetchedRecordZoneChangesEvent;
);

unsafe impl Send for CKSyncEngineFetchedRecordZoneChangesEvent {}

unsafe impl Sync for CKSyncEngineFetchedRecordZoneChangesEvent {}

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

impl CKSyncEngineFetchedRecordZoneChangesEvent {
    extern_methods!(
        #[cfg(feature = "CKRecord")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(modifications))]
        #[unsafe(method_family = none)]
        pub unsafe fn modifications(&self) -> Retained<NSArray<CKRecord>>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(deletions))]
        #[unsafe(method_family = none)]
        pub unsafe fn deletions(&self) -> Retained<NSArray<CKSyncEngineFetchedRecordDeletion>>;
    );
}

/// Methods declared on superclass `CKSyncEngineEvent`.
impl CKSyncEngineFetchedRecordZoneChangesEvent {
    extern_methods!(
        #[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>;
    );
}

extern_class!(
    /// The sync engine finished sending a batch of database changes to the server.
    ///
    /// If a change failed, try to resolve the issue causing the error and make the change again if necessary.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginesentdatabasechangesevent?language=objc)
    #[unsafe(super(CKSyncEngineEvent, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEngineSentDatabaseChangesEvent;
);

unsafe impl Send for CKSyncEngineSentDatabaseChangesEvent {}

unsafe impl Sync for CKSyncEngineSentDatabaseChangesEvent {}

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

impl CKSyncEngineSentDatabaseChangesEvent {
    extern_methods!(
        #[cfg(feature = "CKRecordZone")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(savedZones))]
        #[unsafe(method_family = none)]
        pub unsafe fn savedZones(&self) -> Retained<NSArray<CKRecordZone>>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(failedZoneSaves))]
        #[unsafe(method_family = none)]
        pub unsafe fn failedZoneSaves(&self) -> Retained<NSArray<CKSyncEngineFailedZoneSave>>;

        #[cfg(feature = "CKRecordZoneID")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(deletedZoneIDs))]
        #[unsafe(method_family = none)]
        pub unsafe fn deletedZoneIDs(&self) -> Retained<NSArray<CKRecordZoneID>>;

        #[cfg(feature = "CKRecordZoneID")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(failedZoneDeletes))]
        #[unsafe(method_family = none)]
        pub unsafe fn failedZoneDeletes(&self) -> Retained<NSDictionary<CKRecordZoneID, NSError>>;
    );
}

/// Methods declared on superclass `CKSyncEngineEvent`.
impl CKSyncEngineSentDatabaseChangesEvent {
    extern_methods!(
        #[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>;
    );
}

extern_class!(
    /// The sync engine finished sending a batch of record zone changes to the server.
    ///
    /// If a record save succeeded, you should encode the system fields of this record to use the next time you save. See `encodeSystemFields` on ``CKRecord``.
    ///
    /// If a record deletion succeeded, you should remove any local system fields for that record.
    ///
    /// If the record change failed, try to resolve the issue causing the error and save the record again if necessary.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginesentrecordzonechangesevent?language=objc)
    #[unsafe(super(CKSyncEngineEvent, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEngineSentRecordZoneChangesEvent;
);

unsafe impl Send for CKSyncEngineSentRecordZoneChangesEvent {}

unsafe impl Sync for CKSyncEngineSentRecordZoneChangesEvent {}

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

impl CKSyncEngineSentRecordZoneChangesEvent {
    extern_methods!(
        #[cfg(feature = "CKRecord")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(savedRecords))]
        #[unsafe(method_family = none)]
        pub unsafe fn savedRecords(&self) -> Retained<NSArray<CKRecord>>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(failedRecordSaves))]
        #[unsafe(method_family = none)]
        pub unsafe fn failedRecordSaves(&self) -> Retained<NSArray<CKSyncEngineFailedRecordSave>>;

        #[cfg(feature = "CKRecordID")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(deletedRecordIDs))]
        #[unsafe(method_family = none)]
        pub unsafe fn deletedRecordIDs(&self) -> Retained<NSArray<CKRecordID>>;

        #[cfg(feature = "CKRecordID")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(failedRecordDeletes))]
        #[unsafe(method_family = none)]
        pub unsafe fn failedRecordDeletes(&self) -> Retained<NSDictionary<CKRecordID, NSError>>;
    );
}

/// Methods declared on superclass `CKSyncEngineEvent`.
impl CKSyncEngineSentRecordZoneChangesEvent {
    extern_methods!(
        #[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>;
    );
}

extern_class!(
    /// The sync engine is about to fetch changes from the server.
    ///
    /// This might be a good signal to prepare your local data store for incoming changes if necessary.
    /// The changes themselves will be delivered via `CKSyncEngineFetchedDatabaseChanges` and `CKSyncEngineFetchedRecordZoneChangesEvent`.
    ///
    /// Note that this event might not always occur every time you call `fetchChanges`.
    /// For example, if you call `fetchChanges` concurrently while the engine is already fetching changes, this event might not be sent.
    /// Similarly, if there's no logged-in account, the engine might short-circuit the call to `fetchChanges`, and this event won't be sent.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginewillfetchchangesevent?language=objc)
    #[unsafe(super(CKSyncEngineEvent, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEngineWillFetchChangesEvent;
);

unsafe impl Send for CKSyncEngineWillFetchChangesEvent {}

unsafe impl Sync for CKSyncEngineWillFetchChangesEvent {}

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

impl CKSyncEngineWillFetchChangesEvent {
    extern_methods!(
        #[cfg(feature = "CKSyncEngine")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(context))]
        #[unsafe(method_family = none)]
        pub unsafe fn context(&self) -> Retained<CKSyncEngineFetchChangesContext>;
    );
}

/// Methods declared on superclass `CKSyncEngineEvent`.
impl CKSyncEngineWillFetchChangesEvent {
    extern_methods!(
        #[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>;
    );
}

extern_class!(
    /// The sync engine is about to fetch record zone changes from the server for a specific zone.
    ///
    /// This might be a good signal to prepare your local data store for incoming changes if necessary.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginewillfetchrecordzonechangesevent?language=objc)
    #[unsafe(super(CKSyncEngineEvent, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEngineWillFetchRecordZoneChangesEvent;
);

unsafe impl Send for CKSyncEngineWillFetchRecordZoneChangesEvent {}

unsafe impl Sync for CKSyncEngineWillFetchRecordZoneChangesEvent {}

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

impl CKSyncEngineWillFetchRecordZoneChangesEvent {
    extern_methods!(
        #[cfg(feature = "CKRecordZoneID")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(zoneID))]
        #[unsafe(method_family = none)]
        pub unsafe fn zoneID(&self) -> Retained<CKRecordZoneID>;
    );
}

/// Methods declared on superclass `CKSyncEngineEvent`.
impl CKSyncEngineWillFetchRecordZoneChangesEvent {
    extern_methods!(
        #[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>;
    );
}

extern_class!(
    /// The sync engine finished fetching record zone changes from the server for a specific zone.
    ///
    /// This might be a good signal to perform any post-processing tasks on a per-zone basis if necessary.
    ///
    /// You should receive one `CKSyncEngineDidFetchRecordZoneChangesEvent` for each `CKSyncEngineWillFetchRecordZoneChangesEvent`.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginedidfetchrecordzonechangesevent?language=objc)
    #[unsafe(super(CKSyncEngineEvent, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEngineDidFetchRecordZoneChangesEvent;
);

unsafe impl Send for CKSyncEngineDidFetchRecordZoneChangesEvent {}

unsafe impl Sync for CKSyncEngineDidFetchRecordZoneChangesEvent {}

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

impl CKSyncEngineDidFetchRecordZoneChangesEvent {
    extern_methods!(
        #[cfg(feature = "CKRecordZoneID")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(zoneID))]
        #[unsafe(method_family = none)]
        pub unsafe fn zoneID(&self) -> Retained<CKRecordZoneID>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(error))]
        #[unsafe(method_family = none)]
        pub unsafe fn error(&self) -> Option<Retained<NSError>>;
    );
}

/// Methods declared on superclass `CKSyncEngineEvent`.
impl CKSyncEngineDidFetchRecordZoneChangesEvent {
    extern_methods!(
        #[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>;
    );
}

extern_class!(
    /// The sync engine finished fetching changes from the server.
    ///
    /// This might be a good signal to perform any post-processing tasks required after persisting fetched changes to disk.
    ///
    /// You should receive one `CKSyncEngineDidFetchChangesEvent` for each `CKSyncEngineWillFetchChangesEvent`.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginedidfetchchangesevent?language=objc)
    #[unsafe(super(CKSyncEngineEvent, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEngineDidFetchChangesEvent;
);

unsafe impl Send for CKSyncEngineDidFetchChangesEvent {}

unsafe impl Sync for CKSyncEngineDidFetchChangesEvent {}

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

impl CKSyncEngineDidFetchChangesEvent {
    extern_methods!(
        #[cfg(feature = "CKSyncEngine")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(context))]
        #[unsafe(method_family = none)]
        pub unsafe fn context(&self) -> Retained<CKSyncEngineFetchChangesContext>;
    );
}

/// Methods declared on superclass `CKSyncEngineEvent`.
impl CKSyncEngineDidFetchChangesEvent {
    extern_methods!(
        #[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>;
    );
}

extern_class!(
    /// The sync engine is about to send changes to the server.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginewillsendchangesevent?language=objc)
    #[unsafe(super(CKSyncEngineEvent, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEngineWillSendChangesEvent;
);

unsafe impl Send for CKSyncEngineWillSendChangesEvent {}

unsafe impl Sync for CKSyncEngineWillSendChangesEvent {}

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

impl CKSyncEngineWillSendChangesEvent {
    extern_methods!(
        #[cfg(feature = "CKSyncEngine")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(context))]
        #[unsafe(method_family = none)]
        pub unsafe fn context(&self) -> Retained<CKSyncEngineSendChangesContext>;
    );
}

/// Methods declared on superclass `CKSyncEngineEvent`.
impl CKSyncEngineWillSendChangesEvent {
    extern_methods!(
        #[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>;
    );
}

extern_class!(
    /// The sync engine finished sending changes to the server.
    ///
    /// You should receive one `CKSyncEngineDidSendChangesEvent` for every `CKSyncEngineWillSendChangesEvent`.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginedidsendchangesevent?language=objc)
    #[unsafe(super(CKSyncEngineEvent, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEngineDidSendChangesEvent;
);

unsafe impl Send for CKSyncEngineDidSendChangesEvent {}

unsafe impl Sync for CKSyncEngineDidSendChangesEvent {}

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

impl CKSyncEngineDidSendChangesEvent {
    extern_methods!(
        #[cfg(feature = "CKSyncEngine")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(context))]
        #[unsafe(method_family = none)]
        pub unsafe fn context(&self) -> Retained<CKSyncEngineSendChangesContext>;
    );
}

/// Methods declared on superclass `CKSyncEngineEvent`.
impl CKSyncEngineDidSendChangesEvent {
    extern_methods!(
        #[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>;
    );
}

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

unsafe impl Send for CKSyncEngineFetchedRecordDeletion {}

unsafe impl Sync for CKSyncEngineFetchedRecordDeletion {}

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

impl CKSyncEngineFetchedRecordDeletion {
    extern_methods!(
        #[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>;

        #[cfg(feature = "CKRecordID")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(recordID))]
        #[unsafe(method_family = none)]
        pub unsafe fn recordID(&self) -> Retained<CKRecordID>;

        #[cfg(feature = "CKRecord")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(recordType))]
        #[unsafe(method_family = none)]
        pub unsafe fn recordType(&self) -> Retained<CKRecordType>;
    );
}

/// [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginezonedeletionreason?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CKSyncEngineZoneDeletionReason(pub NSInteger);
impl CKSyncEngineZoneDeletionReason {
    /// A deletion from your software.
    #[doc(alias = "CKSyncEngineZoneDeletionReasonDeleted")]
    pub const Deleted: Self = Self(0);
    /// A deletion from the user via the iCloud storage UI.
    /// This is an indication that the user wanted all data deleted, so local cached data should be wiped and not re-uploaded to the server.
    #[doc(alias = "CKSyncEngineZoneDeletionReasonPurged")]
    pub const Purged: Self = Self(1);
    /// The user chose to reset all encrypted data for their account.
    /// This is an indication that the user had to reset encrypted data during account recovery, so local cached data should be re-uploaded to the server to minimize data loss.
    #[doc(alias = "CKSyncEngineZoneDeletionReasonEncryptedDataReset")]
    pub const EncryptedDataReset: Self = Self(2);
}

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

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

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

unsafe impl Send for CKSyncEngineFetchedZoneDeletion {}

unsafe impl Sync for CKSyncEngineFetchedZoneDeletion {}

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

impl CKSyncEngineFetchedZoneDeletion {
    extern_methods!(
        #[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>;

        #[cfg(feature = "CKRecordZoneID")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(zoneID))]
        #[unsafe(method_family = none)]
        pub unsafe fn zoneID(&self) -> Retained<CKRecordZoneID>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(reason))]
        #[unsafe(method_family = none)]
        pub unsafe fn reason(&self) -> CKSyncEngineZoneDeletionReason;
    );
}

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

unsafe impl Send for CKSyncEngineFailedRecordSave {}

unsafe impl Sync for CKSyncEngineFailedRecordSave {}

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

impl CKSyncEngineFailedRecordSave {
    extern_methods!(
        #[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>;

        #[cfg(feature = "CKRecord")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(record))]
        #[unsafe(method_family = none)]
        pub unsafe fn record(&self) -> Retained<CKRecord>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(error))]
        #[unsafe(method_family = none)]
        pub unsafe fn error(&self) -> Retained<NSError>;
    );
}

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

unsafe impl Send for CKSyncEngineFailedZoneSave {}

unsafe impl Sync for CKSyncEngineFailedZoneSave {}

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

impl CKSyncEngineFailedZoneSave {
    extern_methods!(
        #[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>;

        #[cfg(feature = "CKRecordZone")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(recordZone))]
        #[unsafe(method_family = none)]
        pub unsafe fn recordZone(&self) -> Retained<CKRecordZone>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(error))]
        #[unsafe(method_family = none)]
        pub unsafe fn error(&self) -> Retained<NSError>;
    );
}
