2017-05-08 33 views
0

我有一個「喜歡的按鈕」,所有的用戶在同一時間使用它。它應該將雲容器中的相似記錄的值增加1,或者將其減少1。我如何保證更新發生在記錄的最後一個版本?我的意思是Swift 3中的代碼是什麼,它可以保證每個用戶都能得到類似記錄的最終值,並在其他用戶在同一記錄上發送相同操作時應用增量。抱歉,我沒有關於此的代碼。如何讓多個用戶同時更新我的​​一個CloudKit記錄而不重疊?

我讀了約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 
} 
相關問題