0

I'm storing a record with field name "Folders" using an await for CloudKit API function CKDatabase.modifyRecords(...). To ensure my UI reflects the CloudKit data properly I then do an await for CKDatabase.records(matching: CKQuery).

The retrieved records do not reflect the addition of the new record unless I insert a "Task.sleep" call of at least 1 or 2 seconds between the modifyRecords and the records call. My guess is that the CloudKit server is doing indexing or other processing that doesn't finish until after the "records(matching:) call. So how do I query the database at the correct time to reflect the change? Do I need to be using CKSubscription?

Here's a simplified version of the code:

class ExampleManager: ObservableObject {
    @Published var libraryItems: [LibraryItem] = []
    
    var db: CKDatabase {
        let container = CKContainer(identifier: "abcde")
        return container.publicCloudDatabase
    }
    

    // a UI button will cause this function to be called

    @MainActor
    func addFolder(_ name: String) async {
        let record = CKRecord(recordType: "Folder")
        record.setValuesForKeys(["name": name])
        
        do {
            try await db.modifyRecords(saving: [record], deleting: [])
            try await Task.sleep(nanoseconds: 2_000_000_000) // Why?
            libraryItems = await fetchFolders()
        } catch { /* handle errors */ }
    }
    
    @MainActor
    func fetchFolders() async -> [LibraryItem] {
        var folderInfo = [LibraryItem]()
        let predicate = NSPredicate(value: true)
        let queryAll = CKQuery(recordType: "Folder", predicate: predicate)
        
        do {
            let (matchResults, _) = try await db.records(matching: queryAll)
            for mr in matchResults {
                let (ckRecordID, result) = mr
                switch result {
                case .success(let record):
                    let name = record["name"] as! String
                    folderInfo.append(LibraryItem(name, cloudRecordID: ckRecordID))
                    
                case .failure: /* handle error */ break
                }
            }
        } catch { /* handle error */ }
        return folderInfo
    }
}
tdl
  • 297
  • 3
  • 11

0 Answers0