0

My goal is to get User records from CloudKit I specify in an array of CKRecord.IDs, but only if they were updated more recently than my last updated date which I track locally.

I'm doing the following CloudKit query:

var predicate:NSPredicate

if let lastChecked = defaults.object(forKey: "lastUserFetch") as? Date{
  //Subsequent fetches
  predicate = NSPredicate(format: "modificationDate > %@ AND recordID IN %@", argumentArray: [lastChecked, userRecordIDs])

}else{
  //First fetch
  predicate = NSPredicate(format: "recordID IN %@", argumentArray: [userRecordIDs])
}

let query = CKQuery(recordType: "User", predicate: predicate)
let operation = CKQueryOperation(query: query)
...

I initially set lastUserFetch to nil when my app launches, and the "First fetch" part of the query succeeds. I get all the user records back.

But once I set my lastUserFetch date after the query is done:

defaults.set(Date(), forKey: "lastUserFetch")

I get 0 records returned when the modificationDate > %@ portion is included. I, of course, modify records in the CloudKit Dashboard, and I can see that their modificationDate has updated and is newer than my lastUserFetch date, but they still don't get returned in my search results.

How do I combine a modificationDate comparison with a recordID IN query?

Clifton Labrum
  • 13,053
  • 9
  • 65
  • 128
  • Ugh... for being so reliable, CloudKit sure is unreliable. I tried this query on another record type and it worked. So I rebuilt my `User` record type by deleting it in the CloudKit dashboard and reconstructing it, and now it works again. Sheesh. – Clifton Labrum Jan 15 '21 at 20:03

2 Answers2

0

Use an NSCompoundPredicate:

var predicate:NSPredicate

//Every fetch
predicate = NSPredicate(format: "recordID IN %@", argumentArray: [userRecordIDs])

if let lastChecked = defaults.object(forKey: "lastUserFetch") as? Date{
  //Subsequent fetches
  predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [predicate,  NSPredicate(format: "modificationDate > %@", argumentArray: [lastChecked]))
}
let query = CKQuery(recordType: "User", predicate: predicate)
let operation = CKQueryOperation(query: query)
...
Martin
  • 1
  • 1
  • That's a great suggestion, thank you. I tried it and unfortunately it still doesn't seem to work. I can do one of the `NSPredicate`s, but not both. So strange. – Clifton Labrum Jan 15 '21 at 18:11
-1

Make sure you have queryable index created on modificationDate field on cloudKit