【发布时间】:2015-07-18 02:11:26
【问题描述】:
我需要将包含 12000 个项目的字典中的数据导出到 Cloudkit。我尝试使用便捷 API,但在尝试保存到公共数据库时一直达到速率限制。然后我尝试了 Operation API,我得到了类似的错误。我的问题是:如何在不达到限制的情况下将大量数据保存到 cloudkit?
【问题讨论】:
标签: cloudkit
我需要将包含 12000 个项目的字典中的数据导出到 Cloudkit。我尝试使用便捷 API,但在尝试保存到公共数据库时一直达到速率限制。然后我尝试了 Operation API,我得到了类似的错误。我的问题是:如何在不达到限制的情况下将大量数据保存到 cloudkit?
【问题讨论】:
标签: cloudkit
根据CKErrorLimitExceeded 错误代码的文档,您应该
尝试将您的请求重构为多个较小的批次。
因此,如果您的CKModifyRecordsOperation 操作导致CKErrorLimitExceeded 错误,您可以只创建两个CKModifyRecordsOperation 对象,每个对象包含来自失败操作的一半数据。如果您以递归方式执行此操作(因此任何拆分操作也可能因超出限制错误而失败,再次拆分为两部分),那么您最终应该得到一些 CKModifyRecordsOperation 对象,它们的记录数足够少以避免错误.
【讨论】:
如果你有自己的服务器,你可以试试CloudKit Web Service API。
【讨论】:
在 iOS 10 中,每个操作允许的最大记录数为 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
}
【讨论】: