Kokotoni Wolf
Kokotoni Wolf

Reputation: 1

Export records to cloudkit

I need to export data from a dictionary of 12 thousand items to Cloudkit. I tried to use the convenience API but I keep hitting the rate limit while trying to save to the public database. I then tried the Operation API and I got a similar error. My question is: how to save a very large amount of data to cloudkit without hitting the limits?

Upvotes: 0

Views: 512

Answers (3)

Jonny
Jonny

Reputation: 2084

In iOS 10, the maximum permitted record count per operation is 400.

/// The system allowed maximum record modifications count.
///
/// If excute a CKModifyRecordsOperation with more than 400 record modifications, system will return a CKErrorLimitExceeded error.
private let maximumRecordModificationsLimit = 400

private func modifyRecords(recordsToSave: [CKRecord], recordIDsToDelete: [CKRecordID], previousRetryAfterSeconds: TimeInterval = 0, completion: ((Bool) -> Void)? = nil) {

    guard !recordsToSave.isEmpty || !recordIDsToDelete.isEmpty else {
        completion?(true)
        return
    }

    func handleLimitExceeded() {
        let recordsToSaveFirstSplit = recordsToSave[0 ..< recordsToSave.count / 2]
        let recordsToSaveSecondSplit = recordsToSave[recordsToSave.count / 2 ..< recordsToSave.count]
        let recordIDsToDeleteFirstSplit = recordIDsToDelete[0 ..< recordIDsToDelete.count / 2]
        let recordIDsToDeleteSecondSplit = recordIDsToDelete[recordIDsToDelete.count / 2 ..< recordIDsToDelete.count]

        self.modifyRecords(recordsToSave: Array(recordsToSaveFirstSplit), recordIDsToDelete: Array(recordIDsToDeleteFirstSplit))
        self.modifyRecords(recordsToSave: Array(recordsToSaveSecondSplit), recordIDsToDelete: Array(recordIDsToDeleteSecondSplit), completion: completion)
    }

    if recordsToSave.count + recordIDsToDelete.count > maximumRecordModificationsLimit {
        handleLimitExceeded()
        return
    }

    // run CKModifyRecordsOperation at here
}

Upvotes: 0

Ramon
Ramon

Reputation: 8424

If you have your own server, you could try the CloudKit Web Service API.

Upvotes: 0

Eric Allam
Eric Allam

Reputation: 187

According to the docs for the CKErrorLimitExceeded error code, you should

Try refactoring your request into multiple smaller batches.

So if your CKModifyRecordsOperation operation results in the CKErrorLimitExceeded error, you can just create two CKModifyRecordsOperation objects, each with half the data from the failed operation. If you do that recursively (so any of the split operations could also fail with the limit exceeded error, splitting again in two) then you should eventually get a number of CKModifyRecordsOperation objects that have a small enough number of records to avoid the error.

Upvotes: 1

Related Questions