Coder1224
Coder1224

Reputation: 1835

CKModifyRecordsOperation error retry logic

I am new to CloudKit and have figured out CKModifyRecordsOperation with basic cases of add/remove/delete of one CKRecord at a time. I want to use it to pass in multiple recordsToSave and recordIDsToDelete. I know that I need to do a retry when error.userInfo[CKErrorRetryAfterKey] has a value. My question is, how do I retry this operation? I am stuck figuring out how to know what records to retry. Do I have to retry all records? Which completion block can I do a retry in, or is it both?

My code is below with comments where I don't understand how to retry.

func modifyCkRecs(recsToAddOrMod: [CKRecord]?, recordIDsToDelete:[CKRecordID]?, numTries: Int) {


let ops = CKModifyRecordsOperation(recordsToSave: recsToAddOrMod, recordIDsToDelete: recordIDsToDelete)
ops.savePolicy = CKRecordSavePolicy.AllKeys

ops.perRecordCompletionBlock =  { record, error in

  if let error = error {

    var message = error.localizedDescription
    if error.code == CKErrorCode.NotAuthenticated.rawValue {
      print("Not authenticated")
      message = "If you want your data the same on all your Apple devices, then log into iCloud on your device and make sure the iCloud drive is turned on for this app.\nTo enable iCloud, go to Settings -> iCloud"
    }
    if error.code == CKErrorCode.ServiceUnavailable.rawValue {
      print("Service unavailable")
    }
    if error.code == CKErrorCode.RequestRateLimited.rawValue {
      print("Request Rate Limited")
    }
    if error.code == CKErrorCode.NetworkFailure.rawValue {
      print("Network failure!!")
    }
    if error.code == CKErrorCode.InvalidArguments.rawValue {
      print("Invalid Arguments!!")
    }
    print("Error msg: \(message)")

//        if let delayTime = self.retryTime(error) {
//          if numTries < CloudKitAPI.MAX_RETRY {
//            
//            dispatch_after(delayTime, dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0)) {
//              self.modifyCkRecs(????,????, numTries: numTries+1)
//            }
//          }
//          else {
//            print("WARNING: Reached MAX number of retry, giving up")
//          }
//        }
  }
  else {
    print("Update was a success!")
    if let updatedRec = record {
      if let coreDataObj = self.convertRecToCoreData(updatedRec) {
        // archive the CKRecord system fields into Core Data
        coreDataObj.archiveCkMetadata(updatedRec)

        // remove from queue
        self.addedOrModQueue.removeValueForKey(coreDataObj.uuid)
        self.saveAMQueue()
      }
    }
  }
}

// TODO: Figure out what this block is good for
ops.modifyRecordsCompletionBlock = { savedRecords, deletedRecordIDs, error in
  if let error = error {

    var message = error.localizedDescription
    if error.code == CKErrorCode.NotAuthenticated.rawValue {
      print("Not authenticated")
      message = "If you want your data the same on all your Apple devices, then log into iCloud on your device and make sure the iCloud drive is turned on for this app.\nTo enable iCloud, go to Settings -> iCloud"
    }
    if error.code == CKErrorCode.ServiceUnavailable.rawValue {
      print("Service unavailable")
    }
    if error.code == CKErrorCode.RequestRateLimited.rawValue {
      print("Request Rate Limited")
    }
    if error.code == CKErrorCode.NetworkFailure.rawValue {
      print("Network failure!!")
    }
    if error.code == CKErrorCode.InvalidArguments.rawValue {
      print("Invalid Arguments!!")
    }
    print("Error msg: \(message)")

    // RETRY LOGIC HERE????
    // SOMETHING LIKE THE ABOVE BUT WITH THESE ARGS:
    // self.modifyCkRecs(recsToAddOrMod, recordIDsToDelete, numTries: numTries+1)
  }
  else {

    // clean up the deleted queue
    if let deletedRecs = deletedRecordIDs {
      for deletedRecId in deletedRecs {
        if let uuid = NSUUID(UUIDString: deletedRecId.recordName), let index = self.deletedQueue.indexOf(uuid) {
          self.deletedQueue.removeAtIndex(index)
        }
      }
      self.saveDQueue()
    }
  }
}

ops.qualityOfService = .Background
privateDB.addOperation(ops)
}

Upvotes: 1

Views: 493

Answers (0)

Related Questions