CloudKitをローカルキャッシュする際のコンフリクト


WWDCのAdvanced CloudKitCloudKit Tips and Tricksを元に記事作成しています。

どのような時にコンフリクトが起きるのか?

レコードがロックされていないとき

0.初期状態

Place Name Age
iCloud Paul 20
デバイスA Paul 20
デバイスB Paul 20

1.デバイスAで変更発生

Place Name Age
iCloud Paul 20
デバイスA John 43
デバイスB Paul 20

2.iCloudに変更適応

Place Name Age
iCloud John 43
デバイスA John 43
デバイスB Paul 20

3.デバイスBで変更発生

Place Name Age
iCloud Jonn 43
デバイスA John 43
デバイスB Ema 20

4.iCloudへ適応

Place Name Age
iCloud Ema 43
デバイスA John 43
デバイスB Ema 20

コンフリクトは起きませんが、おかしなデータが出来上がります。

レコードがロックされている時

レコードの状態管理にはrecordChangeTagが使われます。

0.初期状態

Place Name Age RecordChangeTag
iCloud Paul 20 A
デバイスA Paul 20 A
デバイスB Paul 20 A

1.デバイス1で変更発生

Place Name Age RecordChangeTag
iCloud Paul 20 A
デバイスA John 43 A
デバイスB Paul 20 A

2.iCloudへ適応

Place Name Age RecordChangeTag
iCloud John 43 B
デバイスA John 43 B
デバイスB Paul 20 A

iCloudとデバイス1のrecordChangeTagが同じなら変更可能。その後、新しいタグを生成

3.デバイス2で変更発生

Place Name Age RecordChangeTag
iCloud John 43 B
デバイスA John 43 B
デバイスB Ema 20 A

4.コンフリクト!

iCloudのタグがBなのに対して、デバイス2のタグがAなのでコンフリクトが発生します。

Appleの見解

ほぼ全てでロックアップデートを使ってくれ。そしてコンフリクトの解決をしてくれ。
ロックしないのは以下のような場合:
・ 非常に激しい更新がある場合
・ ローカルの変更を強制したい時(ユーザーの選択によって)