Cloudkit Count Records

Can I receive count of records corresponding to CKQuery from CloudKit?

Aggregation queries are not possible in CloudKit. So you have to query all records and count those. To make sure that all records will be returned, you have to set operation.resultsLimit to a value larger than the count otherwise it could happen that not all records are returned.

CloudKit, NSPredicate to return a count or determine if any records exists , in a private container?

There is no way to get a count.

If you wish to determine if there are any records for a given record type, perform a CKQueryOperation for the given record type. Set the query's predicate to [NSPredicate predicateWithValue:YES] and set the operation's resultLimit to 1.

Then check the results. You'll either get one row back if there are any records or you'll get no rows back (or possible an error, see what happens).

Get the number of records that match a CloudKit query

There are no aggregation functions in CloudKit. The only way to do a count is by fetching all records.

CloudKit returns too many records

I just found out, that there is a bug in CloudKit, that deleted records are somehow hidden still available. I resetted my development environment and imported the data again and I got the correct amount of records returned.

More information can be found in this Stackoverflow post:
Deleted CloudKit records Reappear

Swift CloudKit and CKQuery: how to iteratively retrieve records when queryResultBlock returns a query cursor

No need for queryResultBlock in Swift 5.5.

I use this because my CKRecord types are always named the same as their Swift counterparts. You can replace recordType: "\(Record.self)" with your recordType if you want, instead.

public extension CKDatabase {
/// Request `CKRecord`s that correspond to a Swift type.
///
/// - Parameters:
/// - recordType: Its name has to be the same in your code, and in CloudKit.
/// - predicate: for the `CKQuery`
func records<Record>(
type _: Record.Type,
zoneID: CKRecordZone.ID? = nil,
predicate: NSPredicate = .init(value: true)
) async throws -> [CKRecord] {
try await withThrowingTaskGroup(of: [CKRecord].self) { group in
func process(
_ records: (
matchResults: [(CKRecord.ID, Result<CKRecord, Error>)],
queryCursor: CKQueryOperation.Cursor?
)
) async throws {
group.addTask {
try records.matchResults.map { try $1.get() }
}

if let cursor = records.queryCursor {
try await process(self.records(continuingMatchFrom: cursor))
}
}

try await process(
records(
matching: .init(
recordType: "\(Record.self)",
predicate: predicate
),
inZoneWith: zoneID
)
)

return try await group.reduce(into: [], +=)
}
}
}


Related Topics



Leave a reply



Submit