首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CKShare“服务器记录已更改”错误

CKShare“服务器记录已更改”错误
EN

Stack Overflow用户
提问于 2018-01-23 07:22:36
回答 1查看 276关注 0票数 0

我在保存CKShare时遇到了一个问题。在执行共享时,一切都正常工作,但如果共享被取消并再次尝试共享,我会收到错误:

代码语言:javascript
复制
"Server Record Changed" (14/2004); server message = "client oplock error updating record"

下面是我的分享代码:

代码语言:javascript
复制
func share(_ deck: Deck) {

    let zoneID = CKManager.defaultManager.sharedZone?.zoneID


    if let deckName = deck.name {
        selectedDeckForPrivateShare = deckName
    }

    var records = [CKRecord]()


    let deckRecord = deck.deckToCKRecord(zoneID)

    records.append(deckRecord)


    let reference = CKReference(record: deckRecord, action: .none)

    for index in deck.cards {
        let cardRecord = index.cardToCKRecord(zoneID)
        cardRecord["deck"] = reference
        cardRecord.parent = reference

        records.append(cardRecord)

    }


    let share = CKShare(rootRecord: deckRecord)
    share[CKShareTitleKey] = "\(String(describing: deck.name)))" as CKRecordValue?
    records.append(share)
    let sharingController = UICloudSharingController { (controller, preparationCompletion) in


        let modifyOP = CKModifyRecordsOperation(recordsToSave: records, recordIDsToDelete: nil)

        modifyOP.qualityOfService = .userInteractive
        modifyOP.modifyRecordsCompletionBlock = { (savedRecords,deletedRecordIDs,error) in
            preparationCompletion(share, CKContainer.default(), error)

            controller.delegate = self

            if let error = error {
                print(error)

            }
        }


        self.privateDatabase.add(modifyOP)

    }


    sharingController.delegate = self

    self.present(sharingController, animated: true, completion: {

    })   
}

我使用deckToCKRecord()cardToCKRecord()这两个方法将核心数据转换为CKRecord,以便共享。谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-23 09:14:20

有可能即使共享操作被取消(因为您没有明确说明取消是什么意思),您设置的CKShare记录实际上也会被创建并保存在您的私有数据库中。您只是取消了更改其他用户的参与状态(例如,已邀请)。因此,当您重复此过程时,您正在尝试重新保存相同的CKShare,尽管需要重新设置,因此很可能会修改更改标记。CloudKit发现了这一点,并返回“服务器记录已更改”错误。

如果我没记错,你可以用两种方法中的一种。首先,将CKModifyRecordsOperation变量savePolicy的值设置为.allKeys,例如,就在您设置qualityOfService变量的位置。这将强制要求即使CloudKit在您的服务器上找到该记录,它也会自动覆盖它。如果您确定上传的版本应该始终获胜,这是一个很好的方法(并且只会导致一次网络调用)。

大多数人使用的第二种更通用的方法是首先使用根记录的share变量recordID创建一个CKFetchRecordsOperation。所有的CKRecord对象都有一个share变量,它是一个CKReference,但是如果这个对象还没有被共享,那么这个变量将是空的。如果我是对的,在取消后的第二次尝试中,您将发现根记录的共享引用包含您在第一次尝试时设置的CKShare。因此,获取该共享,然后使用它,启动您的父级和其他引用的其余部分,就像您之前所做的!

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48391834

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档