mirror of
https://github.com/AgentSeal/codeburn.git
synced 2026-10-23 15:19:37 +00:00
50 lines
1.9 KiB
Swift
50 lines
1.9 KiB
Swift
import Foundation
|
|
import UserNotifications
|
|
|
|
/// User preference for proactive update notifications. Absent key is true, so
|
|
/// existing installs get the notification without visiting Settings first.
|
|
enum UpdateNotificationPreference {
|
|
static let defaultsKey = "codeburn.update.notificationsEnabled"
|
|
|
|
static func isEnabled(defaults: UserDefaults = .standard) -> Bool {
|
|
defaults.object(forKey: defaultsKey) as? Bool ?? true
|
|
}
|
|
}
|
|
|
|
/// The notification side of the update check, behind a protocol so tests never
|
|
/// reach `UNUserNotificationCenter.current()`, which aborts in a process that is
|
|
/// not an app bundle (`swift test`, `swift run`).
|
|
@MainActor
|
|
protocol UpdateNotifier: AnyObject {
|
|
func requestAuthorizationIfNeeded() async -> Bool
|
|
func post(title: String, body: String, identifier: String)
|
|
}
|
|
|
|
@MainActor
|
|
final class SystemUpdateNotifier: UpdateNotifier {
|
|
func requestAuthorizationIfNeeded() async -> Bool {
|
|
guard Bundle.main.bundleIdentifier != nil else { return false }
|
|
let center = UNUserNotificationCenter.current()
|
|
switch await center.notificationSettings().authorizationStatus {
|
|
case .authorized, .provisional:
|
|
return true
|
|
case .notDetermined:
|
|
do {
|
|
return try await center.requestAuthorization(options: [.alert])
|
|
} catch {
|
|
NSLog("CodeBurn: notification authorization failed: \(error)")
|
|
return false
|
|
}
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func post(title: String, body: String, identifier: String) {
|
|
let content = UNMutableNotificationContent()
|
|
content.title = title
|
|
content.body = body
|
|
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: nil)
|
|
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
|
|
}
|
|
}
|