0

I want to check for the existence of a record with a certain predicate and, if it doesn't exist, do something:

let publicDatabase = CKContainer.default().publicCloudDatabase
let predicate: NSPredicate!
predicate = NSPredicate(format: "username == %@", usernameText)
let query =  CKQuery(recordType: "user", predicate: predicate)
let configuration = CKQueryOperation.Configuration()
configuration.allowsCellularAccess = true
configuration.qualityOfService = .userInitiated

let queryOperation = CKQueryOperation(query: query)
queryOperation.desiredKeys = ["username"]
queryOperation.queuePriority = .veryHigh
queryOperation.configuration = configuration
queryOperation.resultsLimit = 1
queryOperation.recordFetchedBlock = { (record: CKRecord?) -> Void in
    if let record = record {
    // #1
        print("record \(record)")
    } else {
    // #2
        print("none exists")
    }
}

queryOperation.queryCompletionBlock = { (cursor: CKQueryOperation.Cursor?, error: Error?) -> Void in
    if let error = error {
        print("\(error)")
        return
    }
    
    if let cursor = cursor {
        print("cursor: \(cursor)")
    }
}

publicDatabase.add(queryOperation)

When a record matching the predicate exists, the record is returned as it should, but when it doesn't exist, not even nil gets returned for me to react accordingly. What I mean is ideally I want to execute my code in #2 in response to the nonexistence of any records, but recordFetchedBlock doesn't seem to run in that case.

1 Answer 1

2

The issue here is recordFetchedBlock is only called when you get a record. No record? Then it won't be called. The below approach should do the trick for you:

//define an array to store all records
var allRecords = []

queryOperation.recordFetchedBlock = { record in
    //called once for each record
    //if no results, then it is never called
    //if you get a record, add to the array
    allRecords.append[record]
}

//the query completion block is called at the end of the query (or when all results can't be returned in one block, then called with non-nil cursor value.  Considering that out of scope for this answer.
queryOperation.queryCompletionBlock = { (cursor: CKQueryOperation.Cursor?, error: Error?) in
    if let error = error {
        //handle error
    }
    if let cursor = cursor {
       //handle cursor if exists    
    } 
    if allRecords.count == 0 {
        //my query returned no results
        //take desired action    
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.