我正在尝试创建一个包含唯一值的记录类型,并将作为另一个记录类型的目标引用对象.例如,录制类型 – 电影将包含用户提交的唯一电影列表.而且FavoriteMovies将包含用户参考和电影参考.用户可以从现有电影列表中进行选择,也可以向其中添加新电影.
如果我创建一个新的电影记录,而另一个用户创建一个具有相同名称的新记录(在我检索电影列表之后,但在我尝试添加新电影之前),则会出现问题.这两个新记录被认为是具有不同记录ID的不同记录.这意味着一旦我保存了新的,就会有两个带有保存名称的电影实例.
我无法找到一种方法来对“电影记录类型”执行“如果不存在”类型操作.我可以在查询的completionBlock中进行保存,但这两个操作不是原子事务来保证唯一性.据我所知,CKQueryOperation与CKModifyRecordsOperation链接的情况也是如此.
是否只有在单个事务中不存在该值时才能插入记录?
解决方法
如果我正确理解了您的用例,您可以将movieRecord.recordID.recordName设为电影的名称,并使用带有savePolicy IfServerRecordUnchanged的CKModifyRecordsOperation来有效地保存如果不存在.如果您尝试保存服务器上已存在的记录,它将返回一个您可以忽略的错误:
let saveRecordsOperation = CKModifyRecordsOperation() saveRecordsOperation.recordsToSave = [movieRecord] saveRecordsOperation.savePolicy = .IfServerRecordUnchanged
使用savePolicy IfServerRecordUnchanged此操作将保存新的Movie记录(如果它尚不存在于服务器上)(如果不存在则保存),但在后续尝试覆盖服务器上已存在的Movie记录时将返回以下错误(如果它不是从服务器获取的记录的较新修改版本):
<CKError 0x14d23980: "Server Record Changed" (14/2017); server message = "record to insert already exists">
您可以在perRecordCompletionBlock中处理此冲突,但在您的特定用例中,您可以对冲突错误不做任何操作,因此每条Movie记录将是第一个使用该CKRecordID保存的记录.