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

Posted

技术标签:

【中文标题】Swift/Cloudkit:在拉取时处理用户更改【英文标题】:Swift/Cloudkit: Handling user-changes while pulling 【发布时间】:2018-08-04 09:06:35 【问题描述】:

我从this *** question 和Basic CloudKit Workflow 知道,与 Cloudkit 同步的流行方法是首先推送本地更改,然后拉取远程更改,这样我就可以在推送期间通过看到由于更新版本而失败来检测更改在服务器上。

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

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

一个例子是,在用户对to-be-uploaded stack 上的更改对所述文件夹中的文件进行编辑后,拉取删除了一个文件夹。因此,由于更改已经在本地完成,因此当用户在更改列表上推送操作时,当前拉取工作。

我想到的一种处理方法是在我从服务器拉取时禁止任何用户更改。然后我根据 pull 更改 UI 并再次启用更改。 但是我不知道推送需要多长时间,所以一段时间内 UI 无法更改可能是糟糕的用户体验。

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

【问题讨论】:

【参考方案1】:

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

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

当我尝试推送时肯定会遇到版本错误,是否需要在本地和服务器上合并更改?

为避免此问题,我可以等待更改排队,但将其命名为 proposed 更改,我在拉取期间识别并可以采取行动。如果拉取的更改与proposed 不兼容,我可能会拒绝proposed 更改并通知用户冲突。

注意:此问题与 CKError.Code.serverChangedError 不同,因为它仅与拉取期间所做的更改有关。

TLDR:不应允许拉取、推送和本地更改同时发生。

推送期间的本地更改是可以的,它们只是添加到下一批要推送的更改中。在我推送之前,我必须清空 push-local-changes 批处理并将本地缓存锁定为建议模式,因此可以避免相关问题。 拉取期间的本地更改成为提议的更​​改,它们的有效性必须在合并拉取数据期间或之后确定,并通过通知用户采取行动。

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

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

———————————

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

我不必担心合并冲突,因为我已将推送上的用户更改调整为服务器更改,因此拉取不会使刚刚推送的用户更改无效。

——————

替代方案 3 是:获取所有先前拉取的内容,直到用户在拉取期间没有进行任何更改。然后在合并获取的记录时立即锁定数据库。

注意:上传并修复该记录的合并冲突后,可以放弃对记录的远程更改。

【讨论】:

以上是关于Swift/Cloudkit:在拉取时处理用户更改的主要内容,如果未能解决你的问题,请参考以下文章

在拉取期间解决 Git 合并冲突以支持其更改

GitHub:获取当前在拉取请求中的一个特定文件的所有更改

如何在拉取请求中压缩提交

Git:区分本地和远程标签

Git-TFS - 如何在拉取请求被批准之前确保分支是最新的?

Swift / CloudKit:记录更改后,上传触发“服务记录已更改”