對於我訂閱的每個事件,我最多接收四個推送通知。我經歷了與我的CloudKit訂閱和通知註冊表相關的所有事情,我確信這是一個Apple問題。無論我收到多少通知,我都會將注意力轉向正確處理通知。下面是我在做什麼的簡化版本:爲推送通知生成的網絡呼叫創建串行隊列
func recievePrivatePush(_ pushInfo: [String:NSObject], completion: @escaping()->Void) {
let notification = CKNotification(fromRemoteNotificationDictionary: pushInfo)
let alertBody = notification.alertBody
if let queryNotification = notification as? CKQueryNotification {
let recordID = queryNotification.recordID
guard let body = queryNotification.alertBody else {
return
}
if recordID != nil {
switch body {
case "Notification Type":
let id = queryNotification.recordID
switch queryNotification.queryNotificationReason {
case .recordCreated:
DataCoordinatorInterface.sharedInstance.fetchDataItem(id!.recordName, completion: {
//
})
break
default:
break
}
}
}
}
}
的抓取代碼看起來是這樣的:
func fetchDataItem(_ id: String, completion: @escaping()-> Void) {
if entityExistsInCoreData(id) {return}
let db = CKContainer.default().privateCloudDatabase
let recordID = CKRecordID(recordName: id)
db.fetch(withRecordID: recordID) { (record, error) in
if let topic = record {
//Here I create and save the object to core data.
}
completion()
}
}
我所有的代碼工作,我遇到的問題是,當我收到多個通知,在創建第一個核心數據實體之前啓動多個提取請求,從而產生冗餘的核心數據對象。
我想要做的是找到一種方法來將提取請求添加到串行隊列,以便它們一次處理一個。我可以將我的請求調用放入一個串行隊列中,但回調總是異步運行,因此在第一個數據對象被保存之前,仍然會發出多個提取請求。
我已經使用信號量和調度組,看起來像這樣的圖案的嘗試:
let semaphore = DispatchSemaphore(value: 1)
func recievePrivatePush(_ pushInfo: [String:NSObject], completion: @escaping()->Void) {
_ = semaphore.wait(timeout: .distantFuture)
let notification = CKNotification(fromRemoteNotificationDictionary: pushInfo)
let alertBody = notification.alertBody
if let queryNotification = notification as? CKQueryNotification {
let recordID = queryNotification.recordID
guard let body = queryNotification.alertBody else {
return
}
if recordID != nil {
switch body {
case "Notification Type":
let id = queryNotification.recordID
switch queryNotification.queryNotificationReason {
case .recordCreated:
DataCoordinatorInterface.sharedInstance.fetchDataItem(id!.recordName, completion: {
semaphore.signal()
})
break
default:
break
}
}
}
}
}
一旦上述函數被調用用於所述第二時間,並且semaphore.wait被調用時,所述第一執行網絡請求暫停,導致一個凍結的應用程序。
再次,我想完成它將異步網絡請求添加到一個隊列,使它們一次只有一個,即第一個網絡調用是在第二個請求開始之前完成的。
卡爾,不確定我是否清楚地理解了這個問題,但這裏是一個處理多個[重複]通知的替代方法。它非常直接,只需使用字典即可保存通知,以便您可以輕鬆識別重複項。這樣,即使你得到第二次或第三次或更多的同一事件的通知,這也沒有關係。你只是檢查你的字典,扔掉重複。 – user3069232
問題仍然是通知幾乎同時到達,並由應用程序委託並行處理。在有時間向字典添加鍵值對並檢查它之前,我會得到一些誤報。 – CarlNathan