agentsclimarketplace

Sqd sharing

Skill sitapix/sqlitedata-swift-skills/skills/sqd-sharing

Agent Skills for SQLiteData (Point-Free's GRDB-based SwiftData replacement with CloudKit sync). Covers @Table, fetch wrappers, queries, migrations, and SyncEngine.

Install
npx -y skills add sitapix/sqlitedata-swift-skills --skill sqd-sharing

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use when understanding CloudKit sharing architecture, implementing sharing UI, or debugging share behavior — covers CKShare lifecycle, CKRecord.ID mapping, permissions, UICloudSharingController, share acceptance, and record hierarchies.

SKILL.md

6.6 KB, ~1.5k tokens by cl100k_base, as published. Nobody here has run it

CloudKit Sharing Reference

Apple's CloudKit sharing model, CKRecord.ID mapping, and implementation code.

SQLiteData context: SQLiteData's SyncEngine wraps this API. Understanding CloudKit's sharing model explains why SQLiteData has specific constraints around root records, foreign keys, and sharing. For SQLiteData's higher-level sharing API, see /skill sqd-cloudkit.

CKRecord.ID

CKRecord.ID = record name (String) + zone ID (CKRecordZone.ID)

Record name constraints:

  • ASCII string, max 255 characters
  • Custom names must be unique within the zone
  • Record IDs are unique per database

SQLiteData mapping: Your @Table struct's id: UUID becomes the recordName. This is why SQLiteData requires UUID primary keys — they satisfy CloudKit's uniqueness requirement across devices.

Initializers

convenience init(recordName: String)
convenience init(recordName: String, zoneID: CKRecordZone.ID)

Properties

var recordName: String
var zoneID: CKRecordZone.ID

Related Metadata on CKRecord

PropertyTypeDescription
recordIDCKRecord.IDUnique ID
recordTypeStringApp-defined type name
creationDateDate?First saved to server
modificationDateDate?Last saved to server
recordChangeTagString?Server change token

These metadata fields are available via SyncMetadata.lastKnownServerRecord when you attach the metadatabase.

Cross-Zone References

CKRecord.Reference only works within a single zone. To reference records across zones:

  1. Save the recordName and zone ID strings
  2. Recreate CKRecord.ID and CKRecordZone.ID when needed

Sharing Model

The owner shares records from their private database. Participants see shared records in their shared database.

Two sharing modes:

  • Record zone sharing — shares ALL records in a custom zone
  • Record hierarchy sharing — shares a root record and its descendants

SQLiteData uses record hierarchy sharingSyncEngine.share(record:) shares a root record and its one-foreign-key descendants.

Creating a Share

ApproachUseCKShare Init
Zone sharingAll records in a zoneCKShare(recordZoneID:)
Hierarchy sharingRoot record + descendantsCKShare(rootRecord:)

Share Lifecycle

  1. CreateCKShare(rootRecord:) or CKShare(recordZoneID:)
  2. SaveCKModifyRecordsOperation
  3. Invite — Distribute via UICloudSharingController (iOS) or NSSharingService (macOS)
  4. Accept — Recipient taps URL → system provides CKShare.Metadata → confirm with CKAcceptSharesOperation
  5. Manage — Owner can stop sharing; participant can leave; remove via removeParticipant(_:)

SQLiteData equivalents: syncEngine.share(record:), syncEngine.acceptShare(metadata:), syncEngine.unshare(record:)

Key Info.plist requirement:

<key>CKSharingSupported</key>
<true/>

Required for the system to launch your app when a user taps a share URL.

Permissions

PermissionMeaning
.readOnlyParticipant can view but not modify
.readWriteParticipant can modify shared records
.nonePrivate share (invited only)
public shareAnyone with URL can join

SQLiteData: Write permission is enforced automatically. Catch SyncEngine.writePermissionError on DatabaseError.

UICloudSharingController Implementation

Prerequisites

  • CKSharingSupported = true in Info.plist
  • iCloud capability with CloudKit enabled
  • Both devices signed in with different iCloud accounts

Sharing an unshared record

let sharingController = UICloudSharingController { (_, prepareCompletionHandler) in
    let shareID = CKRecord.ID(recordName: UUID().uuidString, zoneID: zone.zoneID)
    var share = CKShare(rootRecord: unsharedRootRecord, shareID: shareID)
    share[CKShare.SystemFieldKey.title] = "A cool topic to share!" as CKRecordValue
    share.publicPermission = .readWrite

    let op = CKModifyRecordsOperation(recordsToSave: [share, unsharedRootRecord], recordIDsToDelete: nil)
    // ... save and call prepareCompletionHandler
}

Managing an existing share

let sharingController = UICloudSharingController(share: share, container: container)

Presenting the controller

sharingController.delegate = self
sharingController.availablePermissions = [.allowPublic, .allowReadOnly, .allowReadWrite]
present(sharingController, animated: true)

UICloudSharingControllerDelegate

MethodWhen CalledAction
cloudSharingControllerDidSaveShare(_:)Share created successfullyFetch changes, update cache
cloudSharingControllerDidStopSharing(_:)User stopped sharingFetch changes, update cache
cloudSharingController(_:failedToSaveShareWithError:)Save failedAlert error

Record Hierarchies (Parent References)

Child records are automatically shared with their parent:

newNoteRecord.parent = CKRecord.Reference(record: topicRecord, action: .none)

Local Caching with Change Tokens

SQLiteData note: SyncEngine handles all change token tracking internally. The patterns below are Apple's raw CloudKit API — useful for understanding what SyncEngine does under the hood.

Database-level changes

let op = CKFetchDatabaseChangesOperation(previousServerChangeToken: token)
op.changeTokenUpdatedBlock = { newToken in
    self.setServerChangeToken(newToken: newToken, cloudKitDB: cloudKitDB)
}

Zone-level changes

let config = CKFetchRecordZoneChangesOperation.ZoneConfiguration()
config.previousServerChangeToken = getServerChangeToken()
let op = CKFetchRecordZoneChangesOperation(
    recordZoneIDs: [zone.zoneID],
    configurationsByRecordZoneID: [zone.zoneID: config]
)

Key CloudKit Types

TypePurpose
CKShareManages a collection of shared records
CKShare.MetadataDescribes shared record metadata (provided on accept)
CKShare.ParticipantDescribes a user's participation
UICloudSharingControllerStandard sharing UI (iOS)
CKRecord.IDUnique record identifier (name + zone)
CKFetchShareMetadataOperationFetch share metadata from URL
CKAcceptSharesOperationConfirm participation

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,970. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.