CloudKitSynchronizer
A CloudKitSynchronizer
object takes care of making all the required calls to CloudKit to keep your model synchronized, using the provided
ModelAdapter
to interact with it.
public class CloudKitSynchronizer: NSObject
CloudKitSynchronizer
will post notifications at different steps of the synchronization process.
#
InheritanceNSObject
#
Initializersinit(identifier:containerIdentifier:database:adapterProvider:keyValueStore:)
#
Initializes a newly allocated synchronizer.
@objc public init(identifier: String, containerIdentifier: String, database: CloudKitDatabaseAdapter, adapterProvider: AdapterProvider, keyValueStore: KeyValueStore = UserDefaultsAdapter(userDefaults: UserDefaults.standard))
#
Parameters- identifier: Identifier for the
QSCloudKitSynchronizer
. - containerIdentifier: Identifier of the iCloud container to be used. The application must have the right entitlements to be able to access this container.
- database: Private or Shared CloudKit Database
- adapterProvider:
CloudKitSynchronizerAdapterProvider
- keyValueStore: Object conforming to KeyValueStore (
UserDefaultsAdapter
, for example)
#
ReturnsInitialized synchronizer or nil
if no iCloud container can be found with the provided identifier.
#
PropertieserrorDomain
#
public static let errorDomain = "CloudKitSynchronizerErrorDomain"
errorKey
#
public static let errorKey = "CloudKitSynchronizerErrorKey"
identifier
#
More than one CloudKitSynchronizer
may be created in an app.
The identifier is used to persist some state, so it should always be the same for a synchronizer –if you change your app to use a different identifier state might be lost.
@objc public let identifier: String
containerIdentifier
#
iCloud container identifier.
@objc public let containerIdentifier: String
database
#
Adapter wrapping a CKDatabase
. The synchronizer will run CloudKit operations on the given database.
public let database: CloudKitDatabaseAdapter
adapterProvider
#
Provides the model adapter to the synchronizer.
@objc public let adapterProvider: AdapterProvider
keyValueStore
#
Required by the synchronizer to persist some state. UserDefaults
can be used via UserDefaultsAdapter
.
public let keyValueStore: KeyValueStore
syncing
#
Indicates whether the instance is currently synchronizing data.
@objc public internal(set) var syncing: Bool = false
batchSize
#
Number of records that are sent in an upload operation.
@objc public var batchSize: Int = CloudKitSynchronizer.defaultBatchSize
compatibilityVersion
#
@objc public var compatibilityVersion: Int = 0
- When set, if the synchronizer finds records uploaded by a different device using a higher compatibility version,
- it will end synchronization with a
higherModelVersionFound
error.
syncMode
#
Whether the synchronizer will only download data or also upload any local changes.
@objc public var syncMode: SynchronizeMode = .sync
delegate
#
@objc public var delegate: CloudKitSynchronizerDelegate?
defaultBatchSize
#
Default number of records to send in an upload operation.
@objc public static var defaultBatchSize = 200
metadataKeys
#
These keys will be added to CKRecords uploaded to CloudKit and are used by SyncKit internally.
public static let metadataKeys: [String] = [CloudKitSynchronizer.deviceUUIDKey, CloudKitSynchronizer.modelCompatibilityVersionKey]
modelAdapters
#
Model adapters in use by this synchronizer
@objc public var modelAdapters: [ModelAdapter]
#
Methodsshare(for:)
#
Returns the locally stored CKShare
for a given model object.
@objc func share(for object: AnyObject) -> CKShare?
- Parameter object The model object.
#
ReturnsCKShare
stored for the given object.
cloudSharingControllerDidSaveShare(_:for:)
#
Saves the given CKShare
locally for the given model object.
@objc func cloudSharingControllerDidSaveShare(_ share: CKShare, for object: AnyObject)
share The
CKShare
.object The model object.
cloudSharingControllerDidStopSharing(for:)
#
Deletes any CKShare
locally stored for the given model object.
@objc func cloudSharingControllerDidStopSharing(for object: AnyObject)
- object The model object.
This method should be called by your
UICloudSharingControllerDelegate
, whencloudSharingControllerDidStopSharing
is called.
share(object:publicPermission:participants:completion:)
#
Returns a CKShare
for the given model object. If one does not exist, it creates and uploads a new
@objc func share(object: AnyObject, publicPermission: CKShare.Participant.Permission, participants: [CKShare.Participant], completion: ((CKShare?, Error?) -> ())?)
object The model object to share.
publicPermission The permissions to be used for the new share.
#
Parameters- participants: The participants to add to this share.
- completion: Closure that gets called with an optional error when the operation is completed.
removeShare(for:completion:)
#
Removes the existing CKShare
for an object and deletes it from CloudKit.
@objc func removeShare(for object: AnyObject, completion: ((Error?) -> ())?)
object The model object.
completion Closure that gets called on completion.
share(forRecordZoneID:)
#
Returns the locally stored CKShare
for a given record zone.
@available(iOS 15.0, OSX 12, *) @objc func share(forRecordZoneID zoneID: CKRecordZone.ID) -> CKShare?
- Parameter zoneID The record zone ID.
#
ReturnsCKShare
stored for the given object.
cloudSharingControllerDidSaveShare(_:forRecordZoneID:)
#
Saves the given CKShare
locally for the given record zone ID.
@available(iOS 15.0, OSX 12, *) @objc func cloudSharingControllerDidSaveShare(_ share: CKShare, forRecordZoneID zoneID: CKRecordZone.ID)
share The
CKShare
.zoneID The record zone ID..
cloudSharingControllerDidStopSharing(forRecordZoneID:)
#
Deletes any CKShare
locally stored for the given record zone ID
@available(iOS 15.0, OSX 12, *) @objc func cloudSharingControllerDidStopSharing(forRecordZoneID zoneID: CKRecordZone.ID)
- zoneID The record zone ID.
This method should be called by your
UICloudSharingControllerDelegate
, whencloudSharingControllerDidStopSharing
is called.
share(recordZoneID:publicPermission:participants:completion:)
#
Returns a CKShare
for the given record zone. If one does not exist, it creates and uploads a new
@available(iOS 15.0, OSX 12, *) @objc func share(recordZoneID: CKRecordZone.ID, publicPermission: CKShare.ParticipantPermission, participants: [CKShare.Participant], completion: ((CKShare?, Error?) -> ())?)
recordZoneID The ID of the record zone to share.
publicPermission The permissions to be used for the new share.
#
Parameters- participants: The participants to add to this share.
- completion: Closure that gets called with an optional error when the operation is completed.
removeShare(recordZoneID:completion:)
#
Removes the existing CKShare
for the record zone and deletes it from CloudKit.
@available(iOS 15.0, OSX 12, *) @objc func removeShare(recordZoneID: CKRecordZone.ID, completion: ((Error?) -> ())?)
recordZoneID The ID of the record zone to unshare.
completion Closure that gets called on completion.
reuploadRecordsForChildrenOf(root:completion:)
#
Reuploads to CloudKit all CKRecord
s for the given root model object and all of its children (see ParentKey
). This function can be used to ensure all objects in the hierarchy have their parent
property correctly set, before sharing, if their records had been created before sharing was supported.
@objc func reuploadRecordsForChildrenOf(root: AnyObject, completion: @escaping ((Error?) -> ()))
root The root model object.
completion Closure that gets called on completion.
subscriptionID(forRecordZoneID:)
#
Returns identifier for a registered CKSubscription
to track changes.
@objc func subscriptionID(forRecordZoneID zoneID: CKRecordZone.ID) -> String?
#
Parameters- zoneID:
CKRecordZoneID
that is being tracked with the subscription.
#
ReturnsIdentifier of an existing CKSubscription
for the record zone, if there is one.
subscriptionIDForDatabaseSubscription()
#
Returns identifier for a registered CKSubscription
to track changes in the synchronizer's database.
@objc func subscriptionIDForDatabaseSubscription() -> String?
#
ReturnsIdentifier of an existing CKSubscription
for this database, if there is one.
subscribeForChangesInDatabase(completion:)
#
Creates a new database subscription with CloudKit so the application can receive notifications when new changes happen. The application is responsible for registering for remote notifications and initiating synchronization when a notification is received. @see CKSubscription
@objc func subscribeForChangesInDatabase(completion: ((Error?)->())?)
* Creates a new database subscription with CloudKit so the application can receive notifications when new changes happen. The application is responsible for registering for remote notifications and initiating synchronization when a notification is received. @see `CKSubscription`** -Parameter completion Block that will be called after subscription is created, with an optional error.
#
Parameters- completion: Block that will be called after subscription is created, with an optional error.
subscribeForChanges(in:completion:)
#
Creates a new subscription with CloudKit so the application can receive notifications when new changes happen. The application is responsible for registering for remote notifications and initiating synchronization when a notification is received. @see CKSubscription
@objc func subscribeForChanges(in zoneID: CKRecordZone.ID, completion: ((Error?)->())?)
#
Parameters- zoneID:
CKRecordZoneID
to track for changes - completion: Block that will be called after subscription is created, with an optional error.
cancelSubscriptionForChangesInDatabase(completion:)
#
Delete existing database subscription to stop receiving notifications.
@objc func cancelSubscriptionForChangesInDatabase(completion: ((Error?)->())?)
* Delete existing database subscription to stop receiving notifications.** -Parameter completion Block that will be called after subscription is deleted, with an optional error.
#
Parameters- completion: Block that will be called after subscription is deleted, with an optional error.
cancelSubscriptionForChanges(in:completion:)
#
Delete existing subscription to stop receiving notifications.
@objc func cancelSubscriptionForChanges(in zoneID: CKRecordZone.ID, completion: ((Error?)->())?)
#
Parameters- zoneID:
CKRecordZoneID
to stop tracking for changes. - completion: Block that will be called after subscription is deleted, with an optional error.
synchronize(completion:)
#
Synchronize data with CloudKit.
@objc public func synchronize(completion: ((Error?) -> ())?)
#
Parameters- completion: Completion block that receives an optional error. Could be a
SyncError
,CKError
, or any other error found during synchronization.
cancelSynchronization()
#
Cancel synchronization. It will cause a current synchronization to end with a cancelled
error.
@objc public func cancelSynchronization()
resetDatabaseToken()
#
@objc public func resetDatabaseToken()
- Deletes saved database token, so next synchronization will include changes in all record zones in the database.
- This does not reset tokens stored by model adapters.
eraseLocalMetadata()
#
@objc public func eraseLocalMetadata()
- Deletes saved database token and all local metadata used to track changes in models.
- The synchronizer should not be used after calling this function, create a new synchronizer instead if you need it.
deleteRecordZone(for:completion:)
#
Deletes the corresponding record zone on CloudKit, along with any data in it.
@objc public func deleteRecordZone(for adapter: ModelAdapter, completion: ((Error?)->())?)
#
Parameters- adapter: Model adapter whose corresponding record zone should be deleted
- completion: Completion block.
addModelAdapter(_:)
#
Adds a new model adapter to be synchronized with CloudKit.
@objc public func addModelAdapter(_ adapter: ModelAdapter)
#
Parameters- adapter: The adapter to be managed by this synchronizer.
removeModelAdapter(_:)
#
Removes the model adapter so data managed by it won't be synced with CloudKit any more.
@objc public func removeModelAdapter(_ adapter: ModelAdapter)
#
Parameters- adapter: Adapter to be removed from the synchronizer