4

In CloudKit, I tried to save a large number of records by batch processing. However, my app crashed with the following error:

Error pushing local data: <CKError 0x15a69e640: "Limit Exceeded" (27/1020); "Your request contains 561 items which is more than the maximum number of items in a single request (400)">

This is my code:

CKModifyRecordsOperation *modifyRecordsOperation = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:localChanges recordIDsToDelete: localDeletions];
modifyRecordsOperation.savePolicy = CKRecordSaveAllKeys;
 
modifyRecordsOperation.modifyRecordsCompletionBlock = ^(NSArray *savedRecords, NSArray *deletedRecordIDs, NSError *error) {
    if (error) {
        NSLog(@"[%@] Error pushing local data: %@", self.class, error);
    }
};

[privateDatabase addOperation:modifyRecordsOperation];

If I get to fetch a record, it seems all can be obtained by setting the resultsLimit in CKQueryOperation.

https://stackoverflow.com/questions/24191999/cloudkit-count-records

https://stackoverflow.com/questions/26324643/cloudkit-your-request-contains-more-than-the-maximum-number-of-items-in-a-singl

https://forums.developer.apple.com/thread/11121

When I want to save a large number of records in the batch processing using CKModifyRecordsOperation, is there any way to eliminate the limit?

Community
  • 1
  • 1
BB-8
  • 111
  • 5

1 Answers1

5

I'm afraid there is no way to eliminate the limit. And you can't count on it being 400 either - the server may decide to reject a request of any size.

Instead, handle the CKErrorLimitExceeded error as Apple suggests: by refactoring the operation into multiple smaller batches (i.e. multiple CKModifyRecordsOperations).

To ensure the speed of fetching and saving records, the server may reject large operations. When this occurs, a block reports the CKErrorLimitExceeded error. Your app should handle this error, and refactor the operation into multiple smaller batches.

Source: CKModifyRecordsOperation Class Reference

So to summarize:

  1. Attempt a CKModifyRecordsOperation with the batch of records you want to save.
  2. If the operation returns CKErrorLimitExceeded, split the batch of records into multiple smaller batches and submit them as multiple CKModifyRecordsOperations. (A simple split would be to just divide the batch in half, but this depends on factors like whether you have CKReferences amongst the new records in the batch.)
  3. If any of those new CKModifyRecordsOperations fail with CKErrorLimitExceeded, split their records... and so on and so forth.
breakingobstacles
  • 2,815
  • 27
  • 24