What is the proper way to read shared items from the Shared Database in CloudKit

I have an app where I can create and share records with other users. When I share a record and the user accepts it, I can display the shared object right after the `userDidAcceptCloudKitShareWith` gets called and using the `CKFetchRecordsOperation` class to fetch the object, no issues here. My problem is trying to read the shared records directly from the `Shared Database` after the user has accepted the record, closed the app, and reopened the app again.



The following code successfully reads all of the records from the `Private Database` located in a zone called `ListsZone`.



    @IBAction func sharedRecords(_ sender: Any) {
        let privateDatabase = CKContainer.init(identifier: "iCloud.com.mySite.lists").database(with: .private)


        let predicate = NSPredicate(value: true)
        let query = CKQuery(recordType: "Items", predicate: predicate)
       
        let ckRecordZoneID = CKRecordZone(zoneName: "ListsZone")
        let ckRecordID = CKRecord.ID(zoneID: ckRecordZoneID.zoneID)


        privateDatabase.perform(query, inZoneWith:ckRecordID.zoneID){( results , error) in
            guard error == nil else{
                print("Error \(String(describing: error?.localizedDescription))")
                return
            }
            if let itemsFromResults = results{
                print("Items: \(itemsFromResults)")
            }
        }
    }


What I'm expecting is to be able to read the shared records from the `Shared Database` with the same code above except modifying the line below, but it's not working.



let privateDatabase = CKContainer.init(identifier: "iCloud.com.mySite.lists").database(with: .shared)


I get the following error.


"Only shared zones can be accessed in the shared DB"


What am I missing?


What is the proper way to read records from the `Shared Database`?


I was under the impression that users who already accepted a shared record from a user and the records are saved in the `Shared Database` the user could access the records by requiring the `Shared Database` directly as shown in my code above.


FYI - I know there are shared records in the shared database because I can see them in the CloudKit dashboard.

Answered by fsdolphin in 419307022

Apparently the name of your `CustomZone` record changes when it gets added to the Shared Database so, you first need to retrieve all custom zones from the shared database.


I found the answer thanks to the following two threads.


https://stackoverflow.com/questions/40603657/cloudkit-sharing


https://stackoverflow.com/questions/56163096/unable-to-fetch-records-in-a-sharedclouddatabase-custom-zone-using-cloudkit


##CODE:


    @IBAction func readSharedRecords(_ sender: Any) {
       
        let sharedData = CKContainer.default().sharedCloudDatabase
        sharedData.fetchAllRecordZones { (recordZone, error) in
            if error != nil {
                print(error?.localizedDescription ?? "Error")
            }
            if let recordZones = recordZone {
                for i in 0..<recordzones.count{
                    // find the zone you want to query
                    if recordZones[i].zoneID.zoneName == "ListsZone"{
                        self.sharedRecords(zID: recordZones[i].zoneID)
                    }
                }
            }
        }
    }


    func sharedRecords(zID: CKRecordZone.ID){
        let privateDatabase = CKContainer.init(identifier: "iCloud.com.mySite.lists").database(with: .shared)


        let predicate = NSPredicate(value: true)
        let query = CKQuery(recordType: "Items", predicate: predicate)


        privateDatabase.perform(query, inZoneWith: zID){( results , error) in
            guard error == nil else{
                print("Error: \(String(describing: error?.localizedDescription))")
                return
            }
            if let itemsFromResults = results{
                print("Items: \(itemsFromResults)")
            }
        }
    }
Accepted Answer

Apparently the name of your `CustomZone` record changes when it gets added to the Shared Database so, you first need to retrieve all custom zones from the shared database.


I found the answer thanks to the following two threads.


https://stackoverflow.com/questions/40603657/cloudkit-sharing


https://stackoverflow.com/questions/56163096/unable-to-fetch-records-in-a-sharedclouddatabase-custom-zone-using-cloudkit


##CODE:


    @IBAction func readSharedRecords(_ sender: Any) {
       
        let sharedData = CKContainer.default().sharedCloudDatabase
        sharedData.fetchAllRecordZones { (recordZone, error) in
            if error != nil {
                print(error?.localizedDescription ?? "Error")
            }
            if let recordZones = recordZone {
                for i in 0..<recordzones.count{
                    // find the zone you want to query
                    if recordZones[i].zoneID.zoneName == "ListsZone"{
                        self.sharedRecords(zID: recordZones[i].zoneID)
                    }
                }
            }
        }
    }


    func sharedRecords(zID: CKRecordZone.ID){
        let privateDatabase = CKContainer.init(identifier: "iCloud.com.mySite.lists").database(with: .shared)


        let predicate = NSPredicate(value: true)
        let query = CKQuery(recordType: "Items", predicate: predicate)


        privateDatabase.perform(query, inZoneWith: zID){( results , error) in
            guard error == nil else{
                print("Error: \(String(describing: error?.localizedDescription))")
                return
            }
            if let itemsFromResults = results{
                print("Items: \(itemsFromResults)")
            }
        }
    }

When you create the zone it adds the owner name as a suffix, so you need to retrieve that from the record or like said above, by querying the zones again.

What is the proper way to read shared items from the Shared Database in CloudKit
 
 
Q