Fix background notification processing of CloudKit changes.
This commit is contained in:
parent
850d6b5623
commit
ea78b5683d
@ -58,6 +58,8 @@ final class CloudKitAccountDelegate: AccountDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func receiveRemoteNotification(for account: Account, userInfo: [AnyHashable : Any], completion: @escaping () -> Void) {
|
func receiveRemoteNotification(for account: Account, userInfo: [AnyHashable : Any], completion: @escaping () -> Void) {
|
||||||
|
os_log(.debug, log: log, "Processing remote notification...")
|
||||||
|
|
||||||
let group = DispatchGroup()
|
let group = DispatchGroup()
|
||||||
|
|
||||||
zones.forEach { zone in
|
zones.forEach { zone in
|
||||||
@ -68,6 +70,7 @@ final class CloudKitAccountDelegate: AccountDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group.notify(queue: DispatchQueue.main) {
|
group.notify(queue: DispatchQueue.main) {
|
||||||
|
os_log(.debug, log: self.log, "Done processing remote notification...")
|
||||||
completion()
|
completion()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,12 +48,8 @@ class CloudKitAcountZoneDelegate: CloudKitZoneDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func cloudKitDidChange(records: [CKRecord]) {
|
func cloudKitDidModify(changed: [CKRecord], deleted: [CloudKitRecordKey], completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
// We don't batch process these records
|
completion(.success(()))
|
||||||
}
|
|
||||||
|
|
||||||
func cloudKitDidDelete(recordKeys: [CloudKitRecordKey]) {
|
|
||||||
// We don't batch process these records
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func addOrUpdateWebFeed(_ record: CKRecord) {
|
func addOrUpdateWebFeed(_ record: CKRecord) {
|
||||||
|
@ -31,7 +31,8 @@ class CloudKitArticlesZoneDelegate: CloudKitZoneDelegate {
|
|||||||
// Article downloads clean up old articles and statuses
|
// Article downloads clean up old articles and statuses
|
||||||
}
|
}
|
||||||
|
|
||||||
func cloudKitDidChange(records: [CKRecord]) {
|
func cloudKitDidModify(changed: [CKRecord], deleted: [CloudKitRecordKey], completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
|
||||||
database.selectPendingReadStatusArticleIDs() { result in
|
database.selectPendingReadStatusArticleIDs() { result in
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let pendingReadStatusArticleIDs):
|
case .success(let pendingReadStatusArticleIDs):
|
||||||
@ -40,9 +41,10 @@ class CloudKitArticlesZoneDelegate: CloudKitZoneDelegate {
|
|||||||
switch result {
|
switch result {
|
||||||
case .success(let pendingStarredStatusArticleIDs):
|
case .success(let pendingStarredStatusArticleIDs):
|
||||||
|
|
||||||
self.process(records: records,
|
self.process(records: changed,
|
||||||
pendingReadStatusArticleIDs: pendingReadStatusArticleIDs,
|
pendingReadStatusArticleIDs: pendingReadStatusArticleIDs,
|
||||||
pendingStarredStatusArticleIDs: pendingStarredStatusArticleIDs)
|
pendingStarredStatusArticleIDs: pendingStarredStatusArticleIDs,
|
||||||
|
completion: completion)
|
||||||
|
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
os_log(.error, log: self.log, "Error occurred geting pending starred records: %@", error.localizedDescription)
|
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 {
|
private extension CloudKitArticlesZoneDelegate {
|
||||||
|
|
||||||
func process(records: [CKRecord], pendingReadStatusArticleIDs: Set<String>, pendingStarredStatusArticleIDs: Set<String>) {
|
func process(records: [CKRecord], pendingReadStatusArticleIDs: Set<String>, pendingStarredStatusArticleIDs: Set<String>, completion: @escaping (Result<Void, Error>) -> Void) {
|
||||||
|
|
||||||
let receivedUnreadArticleIDs = Set(records.filter( { $0[CloudKitArticlesZone.CloudKitArticleStatus.Fields.read] == "0" }).map({ $0.externalID }))
|
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 }))
|
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 updateableUnstarredArticleIDs = receivedUnstarredArticleIDs.subtracting(pendingStarredStatusArticleIDs)
|
||||||
let updateableStarredArticleIDs = receivedStarredArticleIDs.subtracting(pendingStarredStatusArticleIDs)
|
let updateableStarredArticleIDs = receivedStarredArticleIDs.subtracting(pendingStarredStatusArticleIDs)
|
||||||
|
|
||||||
account?.markAsUnread(updateableUnreadArticleIDs)
|
let group = DispatchGroup()
|
||||||
account?.markAsRead(updateableReadArticleIDs)
|
|
||||||
account?.markAsUnstarred(updateableUnstarredArticleIDs)
|
group.enter()
|
||||||
account?.markAsStarred(updateableStarredArticleIDs)
|
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(()))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,8 +19,7 @@ enum CloudKitZoneError: Error {
|
|||||||
protocol CloudKitZoneDelegate: class {
|
protocol CloudKitZoneDelegate: class {
|
||||||
func cloudKitDidChange(record: CKRecord);
|
func cloudKitDidChange(record: CKRecord);
|
||||||
func cloudKitDidDelete(recordKey: CloudKitRecordKey)
|
func cloudKitDidDelete(recordKey: CloudKitRecordKey)
|
||||||
func cloudKitDidChange(records: [CKRecord]);
|
func cloudKitDidModify(changed: [CKRecord], deleted: [CloudKitRecordKey], completion: @escaping (Result<Void, Error>) -> Void);
|
||||||
func cloudKitDidDelete(recordKeys: [CloudKitRecordKey])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typealias CloudKitRecordKey = (recordType: CKRecord.RecordType, recordID: CKRecord.ID)
|
typealias CloudKitRecordKey = (recordType: CKRecord.RecordType, recordID: CKRecord.ID)
|
||||||
@ -326,9 +325,7 @@ extension CloudKitZone {
|
|||||||
case .success:
|
case .success:
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.refreshProgress?.completeTask()
|
self.refreshProgress?.completeTask()
|
||||||
self.delegate?.cloudKitDidChange(records: changedRecords)
|
self.delegate?.cloudKitDidModify(changed: changedRecords, deleted: deletedRecordKeys, completion: completion)
|
||||||
self.delegate?.cloudKitDidDelete(recordKeys: deletedRecordKeys)
|
|
||||||
completion(.success(()))
|
|
||||||
}
|
}
|
||||||
case .zoneNotFound:
|
case .zoneNotFound:
|
||||||
self.createZoneRecord() { result in
|
self.createZoneRecord() { result in
|
||||||
|
@ -112,7 +112,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
|
|||||||
|
|
||||||
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
|
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
self.resumeDatabaseProcessingIfNecessary()
|
||||||
AccountManager.shared.receiveRemoteNotification(userInfo: userInfo) {
|
AccountManager.shared.receiveRemoteNotification(userInfo: userInfo) {
|
||||||
|
self.suspendApplication()
|
||||||
completionHandler(.newData)
|
completionHandler(.newData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user