2

I have an app where I can share records with other users, everything works when I share a single record, my issue is when I share a record (parent record) which has children records referencing it, I can see the parent record in the Shared Database in the CloudKit Dashboard after the user accepts the share but I don't see any of the related child records.

Based on the WWDC videos and some other threads here at Stack Overflow, the child records are automatically shared when you share the parent record, but it's not what I'm seeing, again, I can see the parent record in the Shared Database but no child records.

Here is an overview of how the app is set up in the CloudKit Dashboard.

In the CloudKit Dashboard, I have a Lists and an Items record type, where the Lists record is the parent of one or many Items. In the Items schema, I have a Reference field type which keeps a reference to its parent list.

Here is the code I'm using to save the parent record.

func shareList(){        
    let share = CKShare(rootRecord: self.list)

    if let listName = self.list.object(forKey: "name") as? String {
        self.listName = self.list.object(forKey: "name") as? String
        share[CKShare.SystemFieldKey.title] = "Sharing \(listName)" as CKRecordValue?

    } else {
        share[CKShare.SystemFieldKey.title] = "" as CKRecordValue?
    }
    share[CKShare.SystemFieldKey.shareType] = "com.mySite.lists" as CKRecordValue

    let sharingViewController = UICloudSharingController(preparationHandler: {(UICloudSharingController, handler: @escaping (CKShare?, CKContainer?, Error?) -> Void) in
        let modRecordsList = CKModifyRecordsOperation(recordsToSave: [self.list, share], recordIDsToDelete: nil)

        modRecordsList.modifyRecordsCompletionBlock = {
            (record, recordID, error) in

            handler(share, CKContainer.default(), error)
        }
        CKContainer.default().privateCloudDatabase.add(modRecordsList)
    })

     sharingViewController.delegate = self
     sharingViewController.availablePermissions = [.allowPrivate]
     self.navigationController?.present(sharingViewController, animated:true, completion:nil)
}

What I'm I missing? Is there any additional set up I need to do when sharing the parent record?

I'm right saying that the child records should automatically be shared alone with the parent record?

Here is a picture that demonstrates the relationship between the items and the list is working in the Private Database.

enter image description here

fs_tigre
  • 10,650
  • 13
  • 73
  • 146

1 Answers1

2

You have to set the parent on each child record using setParent: https://developer.apple.com/documentation/cloudkit/ckrecord/1690507-setparent

Like this:

childRecord.setParent(parentRecord)

I hope that helps.

Clifton Labrum
  • 13,053
  • 9
  • 65
  • 128
  • At what point do I need to do that, before sharing the parent record? Do I really need to do this if the schema already defines the relationship in the private database? I thought this was automatically done. Thanks. – fs_tigre May 10 '20 at 10:32
  • Ok, based on your answer from the following thread this needs to be done at the child record creation. Now I remember hearing something like... **you can do this even before knowing that the user will share the record** in one of the WWCD videos. Thanks. https://stackoverflow.com/questions/52058053/how-to-model-my-cloudkit-data – fs_tigre May 10 '20 at 11:14
  • Confirmed, setting `childRecord.setParent(parentRecord)` when creating new child records did the trick. Thanks a lot for your help. – fs_tigre May 10 '20 at 13:38
  • Hey Clifton, how to get Parent set if I am using Core Data mirroring with NSPersistentCloudKitContainer? I have manually set one-to-many relationship, each Item has it's parentList set. But it does not make Items to appear in shared database, though List appears there well. – bodich Jul 16 '20 at 12:52
  • I'm not sure. I haven't used `NSPersistentCloudKitContainer` yet, sorry. – Clifton Labrum Jul 16 '20 at 18:33