Как поставить в очередь много входящих уведомлений CloudKit
Допустим, я сохранил 50 записей в CloudKit с CKModifyRecordsOperation
как это:
let operation = CKModifyRecordsOperation(recordsToSave: records, recordIDsToDelete: nil)
operation.savePolicy = .changedKeys
operation.modifyRecordsCompletionBlock = { records, _, error in
//...
}
privateDB.add(operation)
На других моих устройствах я получаю 50 различных фоновых уведомлений для каждого CKRecord
что изменилось. Это нормально, я ожидаю этого.
Я обрабатываю каждое входящее уведомление следующим образом:
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
с, что уведомления дают мне.
Как я могу поставить в очередь все входящие уведомления CKRecordID
в течение разумного периода времени, чтобы я мог сделать более эффективным CKFetchRecordsOperation
запрос с более чем одним recordID одновременно?
1 ответ
Я использовал таймер для этого, и он работает довольно хорошо. Обычно я запускаю таймер, когда приходит новое push-уведомление, и сбрасываю его каждый раз, когда приходит дополнительное уведомление. Тем временем я собираю все 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)
}
}
}