Hello,
I am building an iOS app that uses NSPersistentCloudKitContainer with a two-store
configuration (.private + .shared), following the "Sharing Core Data objects between
iCloud users" sample. Sharing works in one direction only: the owner's records reach the
participant, but nothing the participant writes is ever exported.
I have spent a full day isolating this and have ruled out every cause I can think of. I would appreciate guidance on what else to check, or confirmation that this is a limitation I have misunderstood.
I have deliberately kept the details below complete, because the interesting part of this report is not the failure itself but everything that has already been eliminated.
Environment
- Xcode 26.6 (17F113)
- Owner device: iPhone 15 Pro, iOS 26.5.2
- Participant device: iPhone 13 mini, iOS 26.0.1
- Two devices, two different iCloud accounts
- CloudKit container:
iCloud.com.onton.quipuledger, Development environment NSPersistentCloudKitContainerwith two stores:private.sqlite—databaseScope = .privateshared.sqlite—databaseScope = .shared- Both created exactly as in the sample (the shared description is a
copy()of the private one, with a newNSPersistentCloudKitContainerOptionswhose scope is.shared)
- Both stores have
NSPersistentHistoryTrackingKeyandNSPersistentStoreRemoteChangeNotificationPostOptionKeyset viewContexthastransactionAuthor,mergePolicy(NSMergeByPropertyObjectTrumpMergePolicy) andautomaticallyMergesChangesFromParent = true
What works
- The owner calls
share(_:to:)with a set of objects and gets aCKShare. - The owner sets
publicPermission = .readWrite, saves the share viaCKDatabase.modifyRecords, then callspersistUpdatedShare(_:in:). - The participant accepts the invitation link. All shared records arrive correctly
in the participant's
shared.sqlite(164 objects), and subsequent owner-side changes continue to arrive. Import events succeed.
What fails
Every export from the participant's .shared store fails, regardless of what is
written. On the participant device:
- New object assigned to the shared store via
context.assign(_:to:)→ never exported - Update to an existing record that arrived from the owner → never exported
- Both are saved successfully to the local store (verified by reading the sqlite file) and appear in the persistent history
The corresponding NSPersistentCloudKitContainer.Event reports:
type: .export
succeeded: false
error: NSCocoaErrorDomain Code=134060
userInfo: [:] // completely empty — no underlying error
countAffectedObjects: 0
Reading the store's internal metadata tables shows the export never begins:
ANSCKEXPORTMETADATA— empty (no history token was ever recorded)ANSCKEXPORTEDOBJECT— 0 rowsANSCKEXPORTOPERATION— 0 rows
Meanwhile the same device's .private store exports successfully, and the owner device's
.private store (which holds the shared zone) exports successfully as well.
What I have ruled out
- Permissions. On the participant,
share.currentUserParticipantreportspermission == .readWrite,role == .publicUser,acceptanceStatus == .accepted. - Record types. All types exist in the Development schema (verified in CloudKit
Console). I also ran
initializeCloudKitSchema()to be certain. - Server-side rejection. The CloudKit Console Logs show no errors at all — the request never reaches the server.
- The records themselves. Failure is independent of content: a single entity with no relationships fails exactly like a multi-object graph.
- Association with the share.
fetchShares(matching:)on the participant returns the correct share for the record, with the correct zone name and owner name. Core Data does know the object belongs to the shared zone. - Corrupted mirroring metadata. Deleting and reinstalling the app on the participant device reproduces the problem from a clean state.
- CloudKit itself refusing participant writes. Using the raw CloudKit API on the same
device, I saved a
CKRecorddirectly into the same shared zone — this succeeded, and the owner device received a push notification for it. So the account, the zone, the permissions and the record type are all fine; only the Core Data mirroring path fails.
Question
Given that Core Data correctly associates the object with the share, and that the same
device can write to the same zone through the raw CloudKit API, why would the mirroring
delegate never schedule an export for the .shared store?
Specifically:
- Is exporting participant-side changes from a
.sharedstore supported byNSPersistentCloudKitContainer? The sample project demonstrates share management and owner-side writes, but I could not find an example of a participant creating or modifying objects in the shared store. - If it is supported, what would cause
NSCocoaErrorDomain 134060with an emptyuserInfoand zero affected objects? Is there a way to obtain the underlying reason? (-com.apple.CoreData.CloudKitDebug 1produced no additional output for me when the app was launched viadevicectl.) - Is there any additional setup required on the participant side beyond accepting the share — for example, does a newly created object need to be related to an object that is already part of the share in order to be exported?
Thank you very much for your help.