From d30987ca0aff458feefd0e2c98e1eb4e014fc7c1 Mon Sep 17 00:00:00 2001 From: Maurice Parker Date: Wed, 29 Apr 2020 15:46:29 -0500 Subject: [PATCH] Use main thread operation to only allow one remote notification at a time to run. --- iOS/AppDelegate.swift | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/iOS/AppDelegate.swift b/iOS/AppDelegate.swift index 32205f2a0..bbadde622 100644 --- a/iOS/AppDelegate.swift +++ b/iOS/AppDelegate.swift @@ -24,6 +24,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD private var syncBackgroundUpdateTask = UIBackgroundTaskIdentifier.invalid var syncTimer: ArticleStatusSyncTimer? + private let remoteNotificationoperationQueue = MainThreadOperationQueue() var shuttingDown = false { didSet { @@ -111,14 +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) - } - } + func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completion: @escaping (UIBackgroundFetchResult) -> Void) { + let op = RemoteNotificationOperation(userInfo: userInfo, completion: completion) + remoteNotificationoperationQueue.add(op) } func applicationWillTerminate(_ application: UIApplication) { @@ -395,3 +391,31 @@ private extension AppDelegate { } } + +class RemoteNotificationOperation: MainThreadOperation { + + // MainThreadOperation + public var isCanceled = false + public var id: Int? + public weak var operationDelegate: MainThreadOperationDelegate? + public var name: String? = "RemoteNotificationOperation" + public var completionBlock: MainThreadOperation.MainThreadOperationCompletionBlock? + + private var userInfo: [AnyHashable : Any] + private var completion: (UIBackgroundFetchResult) -> Void + + init(userInfo: [AnyHashable : Any], completion: @escaping (UIBackgroundFetchResult) -> Void) { + self.userInfo = userInfo + self.completion = completion + } + + func run() { + appDelegate.resumeDatabaseProcessingIfNecessary() + AccountManager.shared.receiveRemoteNotification(userInfo: userInfo) { + appDelegate.suspendApplication() + self.completion(.newData) + self.operationDelegate?.operationDidComplete(self) + } + } + +}