Cannot delete CKRecords with `.parent` set

最后都变了- 提交于 2021-01-24 09:20:56

问题


I am using CloudKit Sharing and am having an issue deleting records. I create two records: an Entry and an Asset. If I set the .parent of the Asset to point to the Entry, then when I attempt to delete both the Entry and the Asset in the same batch, it fails with a reference violation error:

<CKError 0x600002ac2190: \"Reference Violation\" (31/2025); server message = \"Record delete would violate validating reference ([a1]), rejecting update\"

Details

I create a parent record (Entry) and a child record (Asset), and set the Asset's .parent to the Entry:

let eid = CKRecord.ID(recordName: "e1", zoneID: CKRecordZone.ID(zoneName: "test", ownerName: CKCurrentUserDefaultName))
let e = CKRecord(recordType: "Entry", recordID: eid)
e["title"] = "Entry"

let aid = CKRecord.ID(recordName: "a1", zoneID: CKRecordZone.ID(zoneName: "test", ownerName: CKCurrentUserDefaultName))
let a = CKRecord(recordType: "Asset", recordID: aid)
a["position"] = 1
a.setParent(e)

Then I save both in the same call:

let op = CKModifyRecordsOperation(recordsToSave: [e,a], recordIDsToDelete: nil)
op.modifyRecordsCompletionBlock = { (records, recordIDs, error) in
  print("Returned from modify")
  print("records: \(records)")
  print("error: \(error)")
}
CKContainer.default().privateCloudDatabase.add(op)

The operation completes successfully and the records are properly created in CloudKit.

But, when I attempt to delete both:

let op = CKModifyRecordsOperation(recordsToSave: nil, recordIDsToDelete: [eid, aid])
op.modifyRecordsCompletionBlock = { (records, recordIDs, error) in
  print("Returned from modify")
  print("records: \(records)")
  print("deleted: \(recordIDs)")
  print("error: \(error)")  
}
CKContainer.default().privateCloudDatabase.add(op)

I get the above error.

Work Arounds

I realize that I could delete the Asset first, and when that returns, delete the Entry. But, my remote management code batches many things together and I don't want to re-work it figure out which things to do first, and I want to minimize the number of remote calls I need.

I've also discovered that if I add another field to the Asset record that references the Entry with a .deleteSelf action, this all works. So, in the above code where I create the Asset, if I add the following (while keeping the setParent() call:

a["entryRef"] = CKRecord.Reference(record: e, action: .deleteSelf)

Then all works correctly.

But, why should I need to create another field I don't need? I would think that sending the deletions in a single call would let CloudKit handle the references properly, without the need for this extra field.

Has anyone experienced this or found a way to work around it without needing the extra reference field? Using CKRecord.References imposes a limit of 750 references on the parent, and I'd rather not have that limit.

来源:https://stackoverflow.com/questions/56796246/cannot-delete-ckrecords-with-parent-set

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!