Build iOS App / Build .ipa and publish source (push) Successful in 31s
Sideloaded apps can't use APNs (no push entitlement without Apple signing), so deliver notifications via an iOS BGAppRefreshTask that polls the monitored repos every ~15 min and fires local notifications (no Apple push needed): - new PRs that appear in the open set - CI status changes on existing PRs Persistence: NotificationState tracks announced PR ids + last-known CI status so we only fire on actual changes, not every poll. AppDelegate registers the background task and reschedules the next one. Info.plist gets UIBackgroundModes fetch + the BGTask identifier. Settings gains a Notifications toggle; also poll after a foreground inbox load so state seeds and changes are caught promptly. Bump to 3.6.
51 lines
1.7 KiB
Swift
51 lines
1.7 KiB
Swift
import UIKit
|
|
import BackgroundTasks
|
|
|
|
/// App delegate that schedules the background refresh task which drives the
|
|
/// push-equivalent notifications (polling the monitored repos).
|
|
///
|
|
/// iOS runs BGAppRefreshTask opportunistically (~every 15 min at best, often
|
|
/// slower), and only when the app has been used recently and isn't force-quit.
|
|
final class AppDelegate: NSObject, UIApplicationDelegate {
|
|
static let taskIdentifier = "com.bueso.giteapr.refresh"
|
|
|
|
func application(_ application: UIApplication,
|
|
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
|
|
registerBackgroundTask()
|
|
return true
|
|
}
|
|
|
|
private func registerBackgroundTask() {
|
|
BGTaskScheduler.shared.register(
|
|
forTaskWithIdentifier: Self.taskIdentifier,
|
|
using: nil
|
|
) { task in
|
|
// Handle the background refresh.
|
|
self.handle(task)
|
|
}
|
|
}
|
|
|
|
private func handle(_ task: BGTask) {
|
|
// Reschedule the next refresh so the chain continues.
|
|
scheduleNextRefresh()
|
|
|
|
let pollTask = Task { @MainActor in
|
|
await NotificationService.shared.poll()
|
|
}
|
|
task.expirationHandler = {
|
|
pollTask.cancel()
|
|
}
|
|
Task {
|
|
await pollTask.value
|
|
task.setTaskCompleted(success: true)
|
|
}
|
|
}
|
|
|
|
/// Schedule the next background refresh (~15 min from now, earliest).
|
|
func scheduleNextRefresh() {
|
|
let request = BGAppRefreshTaskRequest(identifier: Self.taskIdentifier)
|
|
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
|
|
try? BGTaskScheduler.shared.submit(request)
|
|
}
|
|
}
|