6

一意の値を含み、別のレコード タイプへのターゲット参照オブジェクトとして機能するレコード タイプを作成しようとしています。たとえば、レコード タイプ - 映画には、ユーザーが送信した映画の一意のリストが含まれます。また、FavoriteMovies には、Users 参照と Movies 参照が含まれます。ユーザーは、既存の映画のリストから選択するか、新しい映画を追加できます。

この問題は、別のユーザーが同じ名前で新しいレコードを作成しているときに、新しい映画レコードを作成すると発生します (映画のリストを取得した後、新しいレコードを追加しようとする前)。2 つの新しいレコードは、recordID が異なる別のレコードと見なされます。これは、新しいものを保存すると、保存名を持つ映画のインスタンスが 2 つあることを意味します。

映画レコード タイプに対して [存在しない場合に保存] タイプの操作を実行する方法が見つかりません。クエリの completionBlock で保存することはできますが、これら 2 つのアクションは、一意性を保証するアトミック トランザクションにはなりません。私の知る限り、これは との連鎖CKQueryOperationにも当てはまりますCKModifyRecordsOperation

単一のトランザクションに値が存在しない場合にのみレコードを挿入する方法はありますか?

4

1 に答える 1

6

私があなたのユース ケースを正しく理解していれば、movieRecord.recordID.recordName をムービーの名前にして、存在しない場合に効果的に保存CKModifyRecordsOperationするために使用できます。savePolicy 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ますが、特定のユース ケースでは、競合エラーについて何もできないため、各ムービー レコードがその CKRecordID を持つ最初に保存されたレコードになります。

于 2014-07-17T01:13:05.773 に答える