Sqd sharing
Agent Skills for SQLiteData (Point-Free's GRDB-based SwiftData replacement with CloudKit sync). Covers @Table, fetch wrappers, queries, migrations, and SyncEngine.
npx -y skills add sitapix/sqlitedata-swift-skills --skill sqd-sharingAssembled 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
SyncEnginewraps 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
@Tablestruct'sid: UUIDbecomes therecordName. 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
| Property | Type | Description |
|---|---|---|
recordID | CKRecord.ID | Unique ID |
recordType | String | App-defined type name |
creationDate | Date? | First saved to server |
modificationDate | Date? | Last saved to server |
recordChangeTag | String? | Server change token |
These metadata fields are available via
SyncMetadata.lastKnownServerRecordwhen you attach the metadatabase.
Cross-Zone References
CKRecord.Reference only works within a single zone. To reference records across zones:
- Save the
recordNameand zone ID strings - Recreate
CKRecord.IDandCKRecordZone.IDwhen 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 sharing —
SyncEngine.share(record:)shares a root record and its one-foreign-key descendants.
Creating a Share
| Approach | Use | CKShare Init |
|---|---|---|
| Zone sharing | All records in a zone | CKShare(recordZoneID:) |
| Hierarchy sharing | Root record + descendants | CKShare(rootRecord:) |
Share Lifecycle
- Create —
CKShare(rootRecord:)orCKShare(recordZoneID:) - Save —
CKModifyRecordsOperation - Invite — Distribute via
UICloudSharingController(iOS) orNSSharingService(macOS) - Accept — Recipient taps URL → system provides
CKShare.Metadata→ confirm withCKAcceptSharesOperation - 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
| Permission | Meaning |
|---|---|
.readOnly | Participant can view but not modify |
.readWrite | Participant can modify shared records |
.none | Private share (invited only) |
| public share | Anyone with URL can join |
SQLiteData: Write permission is enforced automatically. Catch
SyncEngine.writePermissionErroronDatabaseError.
UICloudSharingController Implementation
Prerequisites
CKSharingSupported = truein 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
| Method | When Called | Action |
|---|---|---|
cloudSharingControllerDidSaveShare(_:) | Share created successfully | Fetch changes, update cache |
cloudSharingControllerDidStopSharing(_:) | User stopped sharing | Fetch changes, update cache |
cloudSharingController(_:failedToSaveShareWithError:) | Save failed | Alert 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:
SyncEnginehandles 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
| Type | Purpose |
|---|---|
CKShare | Manages a collection of shared records |
CKShare.Metadata | Describes shared record metadata (provided on accept) |
CKShare.Participant | Describes a user's participation |
UICloudSharingController | Standard sharing UI (iOS) |
CKRecord.ID | Unique record identifier (name + zone) |
CKFetchShareMetadataOperation | Fetch share metadata from URL |
CKAcceptSharesOperation | Confirm participation |
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.