假设我用CKModifyRecordsOperation
像这样保存50条记录到CloudKit:
let operation = CKModifyRecordsOperation(recordsToSave: records, recordIDsToDelete: nil)
operation.savePolicy = .changedKeys
operation.modifyRecordsCompletionBlock = { records, _, error in
//...
}
privateDB.add(operation)
在其他设备上,每更改一次CKRecord
,我就会收到 50个不同的背景通知。很好,我希望如此。
我这样处理每个入站通知:
func processCloudKitNotification(notification: CKNotification, database: CKDatabase){
guard let notification = notification as? CKQueryNotification else { return }
if let recordID = notification.recordID{
var recordIDs = [CKRecordID]()
switch notification.queryNotificationReason {
case .recordDeleted:
//Delete [-]
//...
default:
//Add and Edit [+ /]
recordIDs.append(recordID)
}
let fetchOperation = CKFetchRecordsOperation(recordIDs: recordIDs)
fetchOperation.fetchRecordsCompletionBlock = { records, error in
//...
}
database.add(fetchOperation)
}
}
但是,由于50个传入的通知中的每一个都是独立的事件,因此该函数被调用50次不同的时间,从而触发了一系列请求,以使用通知给我的CKRecordID
s提取全部记录。< / p>
如何在合理的时间内将所有传入的通知CKRecordID
排入队列,以便一次发出多个recordID来进行效率更高的CKFetchRecordsOperation
请求?
答案 0 :(得分:0)
我最终为此使用了一个计时器,并且效果很好。基本上,我会在收到新的推送通知时启动计时器,并在每次收到其他通知时将其重置。同时,我收集了所有进入的CKRecordID
,然后在计时器触发时处理它们(在通知停止流入之后发生)。
这是我的代码:
var collectNotificationsTimer: Timer?
var recordIDsFromNotifications = [CKRecordID]()
func processCloudKitNotification(notification: CKNotification, database: CKDatabase){
guard let notification = notification as? CKQueryNotification else { return }
guard let recordID = notification.recordID else { return }
//:: 1 :: Collect record IDs from incoming notifications
if notification.queryNotificationReason == .recordDeleted{
//Delete [-]
//...
}else{
//Add and Edit [+ /]
recordIDsFromNotifications.append(recordID)
//:: 2 :: After collecting IDs for 1 second, request a batch of updated records
collectNotificationsTimer?.invalidate()
collectNotificationsTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false){ _ in
let fetchOperation = CKFetchRecordsOperation(recordIDs: recordIDsFromNotifications)
fetchOperation.fetchRecordsCompletionBlock = { records, error in
recordIDsFromNotifications.removeAll()
if let error = error {
checkCloudKitErrorAndRetryRequest(name: "fetchRecordsCompletionBlock", error: error){}
}else{
if let records = records{
//Save records...
}
}
}
database.add(fetchOperation)
}
}
}