diff --git a/deltachat-ios/AppDelegate.swift b/deltachat-ios/AppDelegate.swift index e821f327d..3479aa478 100644 --- a/deltachat-ios/AppDelegate.swift +++ b/deltachat-ios/AppDelegate.swift @@ -20,6 +20,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD var window: UIWindow? var notifyToken: String? + // `bgFetchTimestamp` is set to last enter-background or last remote- or local-wakeup. + // in the minute after these events, subsequent remote- or local-wakeups are skipped - + // in favor to the chance of being awakened when it makes more sense. + var bgFetchTimestamp: Double = 0.0 + // MARK: - app main entry point @@ -167,6 +172,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD // eg. to complete sending messages out and to react to responses. private func registerBackgroundTask() { logger.info("⬅️ registering background task") + bgFetchTimestamp = Double(Date().timeIntervalSince1970) backgroundTask = UIApplication.shared.beginBackgroundTask { [weak self] in // usually, the background thread is finished before in maybeStop() logger.info("⬅️ background expirationHandler called") @@ -341,6 +347,22 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD return } + // from time to time, `didReceiveRemoteNotification` and `performFetchWithCompletionHandler` + // are actually called at the same millisecond. + // + // therefore, if last fetch is less than a minute ago, we skip this call; + // this also lets the completionHandler being called earlier so that we maybe get awakened when it makes more sense. + // + // nb: calling the completion handler with .noData results in less calls overall. + // if at some point we do per-message-push-notifications, we need to tweak this gate. + let nowTimestamp = Double(Date().timeIntervalSince1970) + if nowTimestamp < bgFetchTimestamp + 60 { + logger.info("➡️ fetch was just executed, skipping") + completionHandler(.newData) + return + } + bgFetchTimestamp = nowTimestamp + // we're in background, run IO for a little time dcContext.maybeStartIo() dcContext.maybeNetwork() diff --git a/deltachat-ios/Controller/SettingsController.swift b/deltachat-ios/Controller/SettingsController.swift index ac39ceb6b..3d8c53de3 100644 --- a/deltachat-ios/Controller/SettingsController.swift +++ b/deltachat-ios/Controller/SettingsController.swift @@ -477,17 +477,21 @@ internal final class SettingsViewController: UITableViewController, ProgressAler for name in ["notify-remote-launch", "notify-remote-receive", "notify-local-wakeup"] { let cnt = UserDefaults.standard.integer(forKey: name + "-count") - let startInt = UserDefaults.standard.double(forKey: name + "-start") - let startStr = startInt==0.0 ? "" : " since " + DateUtils.getExtendedRelativeTimeSpanString(timeStamp: startInt) + let startDbl = UserDefaults.standard.double(forKey: name + "-start") + let startStr = startDbl==0.0 ? "" : " since " + DateUtils.getExtendedRelativeTimeSpanString(timeStamp: startDbl) - let timestampInt = UserDefaults.standard.double(forKey: name + "-last") - let timestampStr = timestampInt==0.0 ? "" : ", last " + DateUtils.getExtendedRelativeTimeSpanString(timeStamp: timestampInt) + let timestampDbl = UserDefaults.standard.double(forKey: name + "-last") + let timestampStr = timestampDbl==0.0 ? "" : ", last " + DateUtils.getExtendedRelativeTimeSpanString(timeStamp: timestampDbl) info += "\(name)=\(cnt)x\(startStr)\(timestampStr)\n" } if let appDelegate = UIApplication.shared.delegate as? AppDelegate { info += "notify-token=\(appDelegate.notifyToken ?? "")\n" + + let timestampDbl = appDelegate.bgFetchTimestamp + let timestampStr = timestampDbl==0.0 ? "" : DateUtils.getExtendedRelativeTimeSpanString(timeStamp: timestampDbl) + info += "last-bg-fetch=\(timestampStr)\n" } #if DEBUG