Search code examples
swiftcloudkit

How to create a new shared record in Cloudkit without being the owner of the parent?


I am developing an app which is basically similar to a shared shopping list. I am willing to use Cloudkit.

It does not make sense to share individually every shopping list item, so the idea is to create a sharing at the list level. This way, all items on the list are shared, as explained here

I have successfully implemented this idea. Basically, the owner of the list can create items, and every time an item is created, users who have accepted to share the list with the owner can see the new item in the Shared Database. I have also checked that when a user modifies an existing record in their Shared Database, the modification is reflected in the owner's Private Database.

Now the problem is that someone who is not the owner of the list might want to create a new item. Basically, if 2 people share a shopping list, both of them should be able to add a new thing to to buy on the list! It seems that this is not possible on Cloudkit. In other terms, only the owner of a parentrecord seems to be able to create children records. Has anyone found a solution for such a use case ?


Solution

  • I am answering my own question after investigating more.

    It seems that it's not possible to create a shared record in the Cloudkit console without being the owner, but it's possible from Swift.

    Here is a sample of code to do so:

          let sharedDatabase = CKContainer.default().sharedCloudDatabase
            sharedDatabase.fetchAllRecordZones { (recordZone, error) in
                let myZoneID = recordZone![0].zoneID//Temporary hack
                let query = CKQuery(recordType: "parentRecordType", predicate: NSPredicate(format: "TRUEPREDICATE", argumentArray: nil))
                sharedDatabase.perform(query, inZoneWith: myZoneID) { (records, error) in
                    print(records)
                    let newID = CKRecord.ID(zoneID: myZoneID)
                    let nameRecord = CKRecord(recordType: "childRecordType", recordID: newID)
                     nameRecord.setValue("Created by someone who is not the owner", forKey: "title")
                    nameRecord.parent = CKRecord.Reference(record:records![0], action: .none)
    
    
                     CKContainer.default().sharedCloudDatabase.save(nameRecord) { (savedRecord: CKRecord?, error: Error?) -> Void in
                        print(error)
    
                    }
                }
             }