Parcourir la source

register and unregister background tasks for each fetch

cyberta il y a 4 ans
Parent
commit
76588a1fb7
1 fichiers modifiés avec 22 ajouts et 1 suppressions
  1. 22 1
      deltachat-ios/AppDelegate.swift

+ 22 - 1
deltachat-ios/AppDelegate.swift

@@ -16,6 +16,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
     var locationManager: LocationManager!
     var notificationManager: NotificationManager!
     private var backgroundTask: UIBackgroundTaskIdentifier = .invalid
+    private var fetchBackgroundTasks = [Double: UIBackgroundTaskIdentifier]()
     var reachability = Reachability()!
     var window: UIWindow?
     var notifyToken: String?
@@ -345,6 +346,24 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
         increaseDebugCounter("notify-local-wakeup")
         performFetch(completionHandler: completionHandler)
     }
+    
+    private func unregisterFetchBackgroundTask(timestamp: Double) {
+        let backgroundTask = fetchBackgroundTasks[timestamp]
+        if let backgroundTask = backgroundTask, backgroundTask != .invalid {
+            UIApplication.shared.endBackgroundTask(backgroundTask)
+            fetchBackgroundTasks.removeValue(forKey: timestamp)
+            logger.info("⬅️ fetch background task ended and removed: \(timestamp)")
+        }
+    }
+    
+    private func registerFetchBackgroundTask(timestamp: Double) {
+        logger.info("⬅️ registering fetch background task: \(timestamp)")
+        let backgroundTask = UIApplication.shared.beginBackgroundTask { [weak self] in
+            logger.info("⬅️ fetch background expirationHandler called")
+            self?.unregisterFetchBackgroundTask(timestamp: timestamp)
+        }
+        fetchBackgroundTasks[timestamp] = backgroundTask
+    }
 
     private func performFetch(completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
         // `didReceiveRemoteNotification` as well as `performFetchWithCompletionHandler` might be called if we're in foreground,
@@ -370,6 +389,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
             return
         }
         bgIoTimestamp = nowTimestamp
+        registerFetchBackgroundTask(timestamp: nowTimestamp)
 
         // we're in background, run IO for a little time
         dcContext.maybeStartIo()
@@ -388,8 +408,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
 
             // to avoid 0xdead10cc exceptions, scheduled jobs need to be done before we get suspended;
             // we increase the probabilty that this happens by waiting a moment before calling completionHandler()
-            DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
+            DispatchQueue.main.asyncAfter(deadline: .now() + 3) { [weak self] in
                 logger.info("⬅️ fetch done")
+                self?.unregisterFetchBackgroundTask(timestamp: nowTimestamp)
                 completionHandler(.newData)
             }
         }