How may participants reverse their acceptance of CKShare?

231 views Asked by At

Is there a way to implement the behaviour - participants reverse their acceptances of CKShares? After the participants accept the CKShares, they go over the shared and say oh no I don't want to contribute anything to the shared and I don't even want to keep the shared records in watch lists of their UI interface.

How do we do to remove them from such collaborations (from shared database to be exact)? The use case is very legitimate as people may accept somethings so that having a chance to go over a bit before decide wether they actually contribute their time and efforts into the shared.

I have tried to use CKModifyRecordZonesOperation to delete the shared zone of CloudKit shared database:

var zoneOp = CKModifyRecordZonesOperation(recordZonesToSave: nil, recordZoneIDsToDelete: [zoneID]

zoneOp.database = sharedDB

However, it seems any shared zones can't be deleted from any participants' iOS devices (except for using their development CloudKit Dashboards that may work though) as such attempt is followed by CKError - disallow delete zone...

1

There are 1 answers

1
Tieme On

From the docs: https://developer.apple.com/documentation/cloudkit/ckshare

If a participant attempts to delete the share, CloudKit removes the participant.

Deleting the share is simple:

try await container.sharedCloudDatabase.deleteRecord(withID: shareRecordId)

The question is how to get the original CKShare.recordID?

Zone-wide-share

Re-create the share id of the zone by using the zoneID:

let shareRecordID = CKRecord.ID(
    recordName: CKRecordNameZoneWideShare, // "cloudkit.zoneshare"
    zoneID: zone.zoneID
)

Other shares

For other shares I think you'll have to store the ID when accepting the share:

func windowScene(
    _ windowScene: UIWindowScene, 
    userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShare.Metadata
) {
    let isZoneWide = (metadata.share.recordID.recordName == CKRecordNameZoneWideShare)
    if !isZoneWide { 
        // Store cloudKitShareMetadata.share.recordID somewhere!
    }

    let acceptSharesOperation = CKAcceptSharesOperation(
        shareMetadatas: [cloudKitShareMetadata]
    )
    // ... Accept share code here
}

You might also be able to fetch the accepted shares, but I haven't tried this code:

let query = CKQuery(recordType: "cloudkit.share", predicate: NSPredicate(value: true))
let shares = try await container.sharedCloudDatabase.records(matching: query)