如何让多个用户同时更新我的一条 CloudKit 记录而不重叠?
Posted
技术标签:
【中文标题】如何让多个用户同时更新我的一条 CloudKit 记录而不重叠?【英文标题】:How to let multiple users update one of my CloudKit records at the same time without overlapping? 【发布时间】:2017-05-08 00:37:10 【问题描述】:我有一个“赞”按钮,所有用户同时使用它。它应该将云容器中类似记录的值加一,或减一。如何保证更新发生在记录的最后一个版本?我的意思是 Swift 3 中的代码是什么,它可以保证每个用户都将获得类似记录的最终值并应用增量,而其他用户在同一记录上发送相同的操作?抱歉,我没有可显示的代码。
我读到了CKErrorServerRecordChanged
,但我不知道如何在语法中使用它。如果您有代码示例,那就太好了。
我在 Firebase 中找到了它。它被称为事务,它会一直跟踪记录版本,直到将操作应用于最后一个版本,这样它就不会丢失任何针对该记录的用户操作。
【问题讨论】:
【参考方案1】:好的,不确定这是一个剪切粘贴的答案,但会给你一个模板来使用。它显示了广泛的错误代码处理,例如在重试旁边有一个带有保存操作的操作。您应该能够弄清楚如何使用此代码执行您想要执行的操作。
func files_saveSet()
let newRecord = CKRecord(recordType: "Blah", recordID: sharedDataAccess.iCloudID)
newRecord["Key"] = sharedDataAccess.iCloudLink as CKRecordValue?
var localChanges:[CKRecord] = []
let records2Erase:[CKRecordID] = []
localChanges.append(newRecord)
let saveRecordsOperation = CKModifyRecordsOperation(recordsToSave: localChanges, recordIDsToDelete: records2Erase)
saveRecordsOperation.savePolicy = .changedKeys
saveRecordsOperation.modifyRecordsCompletionBlock = savedRecords, deletedRecordIDs, error in
self.theApp.isNetworkActivityIndicatorVisible = false
guard error == nil else
if let ckerror = error as? CKError
if ckerror.code == CKError.requestRateLimited
let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as? TimeInterval
DispatchQueue.main.async
Timer.scheduledTimer(timeInterval: retryInterval!, target: self, selector: #selector(self.files_saveSet), userInfo: nil, repeats: false)
else if ckerror.code == CKError.zoneBusy
let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as? TimeInterval
DispatchQueue.main.async
Timer.scheduledTimer(timeInterval: retryInterval!, target: self, selector: #selector(self.files_saveSet), userInfo: nil, repeats: false)
else if ckerror.code == CKError.limitExceeded
let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as? TimeInterval
DispatchQueue.main.async
Timer.scheduledTimer(timeInterval: retryInterval!, target: self, selector: #selector(self.files_saveSet), userInfo: nil, repeats: false)
else if ckerror.code == CKError.notAuthenticated
NotificationCenter.default.post(name: Notification.Name("noCloud"), object: nil, userInfo: nil)
else if ckerror.code == CKError.networkFailure
NotificationCenter.default.post(name: Notification.Name("networkFailure"), object: nil, userInfo: nil)
else if ckerror.code == CKError.networkUnavailable
NotificationCenter.default.post(name: Notification.Name("noWiFi"), object: nil, userInfo: nil)
else if ckerror.code == CKError.quotaExceeded
NotificationCenter.default.post(name: Notification.Name("quotaExceeded"), object: nil, userInfo: nil)
else if ckerror.code == CKError.partialFailure
NotificationCenter.default.post(name: Notification.Name("partialFailure"), object: nil, userInfo: nil)
else if (ckerror.code == CKError.internalError || ckerror.code == CKError.serviceUnavailable)
NotificationCenter.default.post(name: Notification.Name("serviceUnavailable"), object: nil, userInfo: nil)
// end of guard statement
return
if error != nil
//print(error!.localizedDescription)
else
//print("ok")
saveRecordsOperation.qualityOfService = .background
privateDB.add(saveRecordsOperation)
theApp.isNetworkActivityIndicatorVisible = true
【讨论】:
以上是关于如何让多个用户同时更新我的一条 CloudKit 记录而不重叠?的主要内容,如果未能解决你的问题,请参考以下文章