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
NSPersistentCloudKitContainer with two stores:
private.sqlite — databaseScope = .private
shared.sqlite — databaseScope = .shared
Both created exactly as in the sample (the shared description is a copy() of the
private one, with a new NSPersistentCloudKitContainerOptions whose scope is .shared)
Both stores have NSPersistentHistoryTrackingKey and
NSPersistentStoreRemoteChangeNotificationPostOptionKey set
viewContext has transactionAuthor, mergePolicy
(NSMergeByPropertyObjectTrumpMergePolicy) and
automaticallyMergesChangesFromParent = true
What works
The owner calls share(_:to:) with a set of objects and gets a CKShare.
The owner sets publicPermission = .readWrite, saves the share via
CKDatabase.modifyRecords, then calls persistUpdatedShare(_: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 rows
ANSCKEXPORTOPERATION — 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.currentUserParticipant reports
permission == .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 CKRecord directly 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 .shared store supported by
NSPersistentCloudKitContainer? 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 134060 with an empty
userInfo and zero affected objects? Is there a way to obtain the underlying reason?
(-com.apple.CoreData.CloudKitDebug 1 produced no additional output for me when the
app was launched via devicectl.)
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.