Deleting CloudKit Records Swift 4

1.2k views Asked by At

I am having issues deleting CloudKit records. This is my first time dealing with the API and apparently there are two ways to do this.

Saving records is straight forward and ostensibly so is deleting them, except this doesn't do it:

func deleteRecords() {

    let recordID = record.recordID
    publicDatabase.delete(withRecordID: recordID) { (recordID, error) in
        guard let recordID = recordID else {
        print(error!.localizedDescription)
            return
    }
        print("Record \(recordID) was successfully deleted")
    }
}

I understand using a ckModifyRecordsOperation is another way to do this but this is a batch operation. I only need to delete one record at a time. Here's my code for that:

 func batchDelete() {
    let recordIDsToDelete = [CKRecordID]()
    let operation = CKModifyRecordsOperation(recordsToSave: nil, recordIDsToDelete: recordIDsToDelete)
    operation.modifyRecordsCompletionBlock = { savedRecords, deletedRecordIDs, error in
        // handle errors here
    }
    publicDatabase.add(operation)
    print("Batch \(recordIDsToDelete) record was successfully deleted")
}

Neither of these separately or together are working for me.

1

There are 1 answers

1
Thunk On

You are correct, there are two ways. The first way you describe is referred to by Apple as a "convenience" function. If you're just deleting a single record, it's probably the quickest option to implement. However, each convenience operation conducts its own trip to the database. If you loop through thousands of records and delete them individually with the convenience function, you're going to use a lot of your cloudKit quota making a series of individual calls.

The second option, the operation, let's you batch the deletes and send them in one operation. Generally, this will be a more efficient use of your cloudkit quotas. But, according to Apple docs, there's no technical difference between the two; the the convenience function is just a wrapper to the operation.

Now, to your specific problem, the operation has two separate completion blocks: perRecordCompletionBlock and modifyRecordsCompletionBlock. As the names imply, the first block is called after each and every record is processed in the operation and that's where errors are surfaced. Make sure you implement perRecordCompletionBlock and check for errors there (and then you'll have to decide if your error handling steps belong in the perRecordCompletionBlock or the modifyRecordsCompletionBlock).

Finally, if the operation (or convenience function) is running and you confirm that the completion blocks fire without errors but the record still doesn't delete, this typically indicates you passed nil rather than a valid record to the deletion.