Swift / Cloudkit:在拉动时处理用户更改

时间:2018-08-04 09:06:35

标签: swift cloudkit

我从this StackOverflow questionBasic CloudKit Workflow知道,与Cloudkit同步的普遍方法是先推送本地更改,然后提取远程更改,这样我就可以在推送过程中发现失败而检测到更改由于服务器上的版本较新。

但是如果我拉长一点会怎样

  • 并且用户进行了更改,而用户更改使所提取的数据无效?
  • 由于文件已被删除,用户进行的更改已过时了吗?

一个示例是用户在to-be-uploaded stack上进行更改后,对用户对该文件夹中的文件进行编辑后,pull删除文件夹。因此,由于更改已在本地完成,因此在用户将操作推入更改列表时,拉动当前有效。

我想到的一种解决方法是在我从服务器中拉出时禁止任何用户更改。然后,根据拉动更改UI并再次启用更改。
但是我不知道推送需要花费多长时间,因此UI一段时间无法更改内容可能会带来糟糕的用户体验。

其他人如何处理(或避免使用)使用户进行的更改无效的拉动?

1 个答案:

答案 0 :(得分:0)

我试图避免覆盖拉动时所做的用户更改。例: 我有一个文件,并且用户在下拉文件的另一个版本时保存了对它的更改。

本地用户更改已排队。 因此,一旦完成拉动并开始推送用户本地更改,我就会推送不再反映本地缓存的更改。

当我尝试将其推送时,肯定会收到版本错误,是否有必要在本地和服务器两者上合并更改?

为避免此问题,我可以等待对更改进行排队,但是将其命名为proposed更改,我可以在拉动过程中识别该更改并且可以执行此操作。如果请求的更改与proposed不兼容,我可以拒绝proposed更改并将冲突通知用户。

注意:此问题与CKError.Code.serverChangedError是分开的,因为它仅与提取期间所做的更改有关。

TLDR:拉,推和本地更改不应同时发生。

  • 在推送期间进行本地更改是可以的,它们只是添加到要推送的下一批更改中。不过,在我进行推送之前,我必须清空push-local-changes批处理并将本地缓存锁定为proposal-mode,因此可以避免出现问题。
  • 拉动期间的局部更改变为建议的更改,必须在合并拉动数据期间或之后并通过通知用户采取措施来确定其有效性。

必须将提议的更改链接到本地​​缓存对象,以便拉合并可以通知提议的更改并在其中存储对象已更改,因此提议的更改可能无效。

链接到建议的更改的另一种方法是在对象中具有版本号,并在每次更改时增加版本号(尤其是在合并合并的更改期间)。在创建时,建议的更改将保留要更改的对象的版本号。拉合并后,当评估提议的更改时,可以通过将对象内部的版本号与对象的提议更改中存储的版本号进行比较来进行评估。

————————————

另一种选择是-在拉出所有更改之后-不直接合并它们,而是先推送更改,直到不再有本地更改,然后阻止本地更改并合并拉出的更改。

我不必担心合并冲突,因为我已经将推送中的用户更改适应了服务器更改,因此,推送不会使刚进行的用户更改无效。

——————

替代3是:获取所有先前拉出的内容,直到用户在拉出过程中未进行任何更改为止。然后在合并获取的记录时不久锁定数据库。

注意:在上传一条记录后,可以放弃对一条记录的远程更改,并解决了该记录的合并冲突。