diff --git a/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift b/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift index c6bd7d04d..879b8bd0e 100644 --- a/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift +++ b/Frameworks/Account/CloudKit/CloudKitAccountDelegate.swift @@ -58,6 +58,8 @@ final class CloudKitAccountDelegate: AccountDelegate { } func receiveRemoteNotification(for account: Account, userInfo: [AnyHashable : Any], completion: @escaping () -> Void) { + os_log(.debug, log: log, "Processing remote notification...") + let group = DispatchGroup() zones.forEach { zone in @@ -68,6 +70,7 @@ final class CloudKitAccountDelegate: AccountDelegate { } group.notify(queue: DispatchQueue.main) { + os_log(.debug, log: self.log, "Done processing remote notification...") completion() } } diff --git a/Frameworks/Account/CloudKit/CloudKitAccountZoneDelegate.swift b/Frameworks/Account/CloudKit/CloudKitAccountZoneDelegate.swift index 27056ecd1..b00561ad5 100644 --- a/Frameworks/Account/CloudKit/CloudKitAccountZoneDelegate.swift +++ b/Frameworks/Account/CloudKit/CloudKitAccountZoneDelegate.swift @@ -48,14 +48,10 @@ class CloudKitAcountZoneDelegate: CloudKitZoneDelegate { } } - func cloudKitDidChange(records: [CKRecord]) { - // We don't batch process these records + func cloudKitDidModify(changed: [CKRecord], deleted: [CloudKitRecordKey], completion: @escaping (Result) -> Void) { + completion(.success(())) } - func cloudKitDidDelete(recordKeys: [CloudKitRecordKey]) { - // We don't batch process these records - } - func addOrUpdateWebFeed(_ record: CKRecord) { guard let account = account, let urlString = record[CloudKitAccountZone.CloudKitWebFeed.Fields.url] as? String, diff --git a/Frameworks/Account/CloudKit/CloudKitArticlesZoneDelegate.swift b/Frameworks/Account/CloudKit/CloudKitArticlesZoneDelegate.swift index 5d469558f..31bed3d58 100644 --- a/Frameworks/Account/CloudKit/CloudKitArticlesZoneDelegate.swift +++ b/Frameworks/Account/CloudKit/CloudKitArticlesZoneDelegate.swift @@ -31,7 +31,8 @@ class CloudKitArticlesZoneDelegate: CloudKitZoneDelegate { // Article downloads clean up old articles and statuses } - func cloudKitDidChange(records: [CKRecord]) { + func cloudKitDidModify(changed: [CKRecord], deleted: [CloudKitRecordKey], completion: @escaping (Result) -> Void) { + database.selectPendingReadStatusArticleIDs() { result in switch result { case .success(let pendingReadStatusArticleIDs): @@ -40,9 +41,10 @@ class CloudKitArticlesZoneDelegate: CloudKitZoneDelegate { switch result { case .success(let pendingStarredStatusArticleIDs): - self.process(records: records, + self.process(records: changed, pendingReadStatusArticleIDs: pendingReadStatusArticleIDs, - pendingStarredStatusArticleIDs: pendingStarredStatusArticleIDs) + pendingStarredStatusArticleIDs: pendingStarredStatusArticleIDs, + completion: completion) case .failure(let error): os_log(.error, log: self.log, "Error occurred geting pending starred records: %@", error.localizedDescription) @@ -56,15 +58,11 @@ class CloudKitArticlesZoneDelegate: CloudKitZoneDelegate { } - func cloudKitDidDelete(recordKeys: [CloudKitRecordKey]) { - // Article downloads clean up old articles and statuses - } - } private extension CloudKitArticlesZoneDelegate { - func process(records: [CKRecord], pendingReadStatusArticleIDs: Set, pendingStarredStatusArticleIDs: Set) { + func process(records: [CKRecord], pendingReadStatusArticleIDs: Set, pendingStarredStatusArticleIDs: Set, completion: @escaping (Result) -> Void) { let receivedUnreadArticleIDs = Set(records.filter( { $0[CloudKitArticlesZone.CloudKitArticleStatus.Fields.read] == "0" }).map({ $0.externalID })) let receivedReadArticleIDs = Set(records.filter( { $0[CloudKitArticlesZone.CloudKitArticleStatus.Fields.read] == "1" }).map({ $0.externalID })) @@ -76,10 +74,31 @@ private extension CloudKitArticlesZoneDelegate { let updateableUnstarredArticleIDs = receivedUnstarredArticleIDs.subtracting(pendingStarredStatusArticleIDs) let updateableStarredArticleIDs = receivedStarredArticleIDs.subtracting(pendingStarredStatusArticleIDs) - account?.markAsUnread(updateableUnreadArticleIDs) - account?.markAsRead(updateableReadArticleIDs) - account?.markAsUnstarred(updateableUnstarredArticleIDs) - account?.markAsStarred(updateableStarredArticleIDs) + let group = DispatchGroup() + + group.enter() + account?.markAsUnread(updateableUnreadArticleIDs) { _ in + group.leave() + } + + group.enter() + account?.markAsRead(updateableReadArticleIDs) { _ in + group.leave() + } + + group.enter() + account?.markAsUnstarred(updateableUnstarredArticleIDs) { _ in + group.leave() + } + + group.enter() + account?.markAsStarred(updateableStarredArticleIDs) { _ in + group.leave() + } + + group.notify(queue: DispatchQueue.main) { + completion(.success(())) + } } diff --git a/Frameworks/Account/CloudKit/CloudKitZone.swift b/Frameworks/Account/CloudKit/CloudKitZone.swift index 17f97a7ac..9cc28defa 100644 --- a/Frameworks/Account/CloudKit/CloudKitZone.swift +++ b/Frameworks/Account/CloudKit/CloudKitZone.swift @@ -19,8 +19,7 @@ enum CloudKitZoneError: Error { protocol CloudKitZoneDelegate: class { func cloudKitDidChange(record: CKRecord); func cloudKitDidDelete(recordKey: CloudKitRecordKey) - func cloudKitDidChange(records: [CKRecord]); - func cloudKitDidDelete(recordKeys: [CloudKitRecordKey]) + func cloudKitDidModify(changed: [CKRecord], deleted: [CloudKitRecordKey], completion: @escaping (Result) -> Void); } typealias CloudKitRecordKey = (recordType: CKRecord.RecordType, recordID: CKRecord.ID) @@ -326,9 +325,7 @@ extension CloudKitZone { case .success: DispatchQueue.main.async { self.refreshProgress?.completeTask() - self.delegate?.cloudKitDidChange(records: changedRecords) - self.delegate?.cloudKitDidDelete(recordKeys: deletedRecordKeys) - completion(.success(())) + self.delegate?.cloudKitDidModify(changed: changedRecords, deleted: deletedRecordKeys, completion: completion) } case .zoneNotFound: self.createZoneRecord() { result in diff --git a/iOS/AppDelegate.swift b/iOS/AppDelegate.swift index 965e34917..a16e92ab2 100644 --- a/iOS/AppDelegate.swift +++ b/iOS/AppDelegate.swift @@ -112,7 +112,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { DispatchQueue.main.async { + self.resumeDatabaseProcessingIfNecessary() AccountManager.shared.receiveRemoteNotification(userInfo: userInfo) { + self.suspendApplication() completionHandler(.newData) } }