mirror of
https://github.com/bulwarkmail/native.git
synced 2026-11-01 08:06:13 +00:00
63 lines
2.4 KiB
Swift
63 lines
2.4 KiB
Swift
import BackgroundTasks
|
|
import Foundation
|
|
import UIKit
|
|
|
|
/// The app's side of PushRenewal: every shared account's subscription is
|
|
/// renewed when the app comes back to the foreground (the JS refresh runs
|
|
/// only on a cold start), and from a background app refresh task that iOS
|
|
/// runs now and then while the app is not used at all.
|
|
///
|
|
/// The config plugin (plugins/ios-push/index.js) compiles this into the app,
|
|
/// calls register() from AppDelegate's didFinishLaunching (BGTaskScheduler
|
|
/// wants its handlers registered before launch ends), and lists the task id
|
|
/// in Info.plist (BGTaskSchedulerPermittedIdentifiers, UIBackgroundModes
|
|
/// fetch).
|
|
enum PushRenewalTask {
|
|
static let identifier = "org.bulwarkmail.mobile.push-renewal"
|
|
/// A subscription lasts seven days; asking twice a day leaves iOS room to
|
|
/// skip runs (it decides when, and whether, the task runs).
|
|
static let interval: TimeInterval = 12 * 60 * 60
|
|
private static var observers: [NSObjectProtocol] = []
|
|
|
|
static func register() {
|
|
let registered = BGTaskScheduler.shared.register(forTaskWithIdentifier: identifier, using: nil) { task in
|
|
guard let refresh = task as? BGAppRefreshTask else {
|
|
task.setTaskCompleted(success: false)
|
|
return
|
|
}
|
|
handle(refresh)
|
|
}
|
|
if !registered { pushLog.error("push renewal task not registered") }
|
|
let center = NotificationCenter.default
|
|
observers = [
|
|
center.addObserver(forName: UIApplication.willEnterForegroundNotification, object: nil, queue: nil) { _ in
|
|
// No token refresh here: the app's own code refreshes on foreground.
|
|
Task { await PushRenewal.renewAll(allowRefresh: false) }
|
|
},
|
|
center.addObserver(forName: UIApplication.didEnterBackgroundNotification, object: nil, queue: nil) { _ in
|
|
schedule()
|
|
},
|
|
]
|
|
}
|
|
|
|
static func schedule() {
|
|
let request = BGAppRefreshTaskRequest(identifier: identifier)
|
|
request.earliestBeginDate = Date(timeIntervalSinceNow: interval)
|
|
do {
|
|
try BGTaskScheduler.shared.submit(request)
|
|
} catch {
|
|
// The simulator has no background refresh.
|
|
pushLog.error("push renewal task not scheduled: \(String(describing: error), privacy: .public)")
|
|
}
|
|
}
|
|
|
|
private static func handle(_ task: BGAppRefreshTask) {
|
|
schedule()
|
|
let work = Task {
|
|
await PushRenewal.renewAll(allowRefresh: true)
|
|
task.setTaskCompleted(success: !Task.isCancelled)
|
|
}
|
|
task.expirationHandler = { work.cancel() }
|
|
}
|
|
}
|