CloudKit - 如何保存记录如果不存在

时间:2014-07-16 15:52:19

标签: ios icloud ios8 cloudkit

我正在尝试创建一个包含唯一值的记录类型,并将作为另一个记录类型的目标引用对象。例如,录制类型 - 电影将包含用户提交的唯一电影列表。而且FavoriteMovies将包含用户参考和电影参考。用户可以从现有电影列表中进行选择,也可以向其中添加新电影。

如果我创建一个新的电影记录,而另一个用户创建一个具有相同名称的新记录(在我检索电影列表之后,但在我尝试添加新电影之前),则会出现问题。这两个新记录被认为是具有不同记录ID的不同记录。这意味着,一旦我保存了新的电影,就会有两个带有保存名称的电影实例。

我无法找到一种方法来对“电影记录类型”执行“如果不存在”类型操作。我可以在查询的completionBlock中进行保存,但这两个操作不是原子事务来保证唯一性。据我所知,将CKQueryOperationCKModifyRecordsOperation链接起来也是如此。

只有在单个事务中不存在该值时才能插入记录吗?

1 个答案:

答案 0 :(得分:6)

如果我正确理解了您的用例,您可以将movieRecord.recordID.recordName设为电影的名称,并使用CKModifyRecordsOperationsavePolicy IfServerRecordUnchanged一起使用,以便有效地保存(如果不存在)。如果您尝试保存服务器上已存在的记录,它将返回一个您可以忽略的错误:

let saveRecordsOperation = CKModifyRecordsOperation()
saveRecordsOperation.recordsToSave = [movieRecord]
saveRecordsOperation.savePolicy = .IfServerRecordUnchanged

使用savePolicy IfServerRecordUnchanged此操作将保存新的电影记录(如果它尚不存在于服务器上)(如果不存在则保存),但会在以后尝试覆盖电影记录时返回以下错误已存在于服务器上(前提是它不是从服务器获取的记录的较新修改版本):

<CKError 0x14d23980: "Server Record Changed" (14/2017); server message = "record to insert already exists">

您可以在perRecordCompletionBlock中处理此冲突,但在您的特定用例中,您可以对冲突错误不做任何操作,因此每条Movie记录将是第一个使用该CKRecordID保存的记录。