mirror of
https://github.com/XcodesOrg/XcodesApp.git
synced 2026-01-06 22:51:09 +01:00
101 lines
3.8 KiB
Swift
101 lines
3.8 KiB
Swift
import Foundation
|
|
import os.log
|
|
import UserNotifications
|
|
|
|
/// Representation of the 3 states of the Notifications permission prompt which may either have not been shown, or was shown and denied or accepted
|
|
/// Unknown is value to indicate that we have not yet determined the status and should not be used other than as a default value before determining the actual status
|
|
public enum NotificationPermissionPromptStatus: Int {
|
|
case unknown, notShown, shownAndDenied, shownAndAccepted
|
|
}
|
|
|
|
public enum XcodesNotificationCategory: String {
|
|
case normal
|
|
case error
|
|
}
|
|
|
|
public enum XcodesNotificationType: String, Identifiable, CaseIterable, CustomStringConvertible {
|
|
case newVersionAvailable
|
|
case finishedInstalling
|
|
|
|
public var id: Self { self }
|
|
|
|
public var description: String {
|
|
switch self {
|
|
case .newVersionAvailable:
|
|
return localizeString("Notification.NewVersionAvailable")
|
|
case .finishedInstalling:
|
|
return localizeString("Notification.FinishedInstalling")
|
|
}
|
|
}
|
|
}
|
|
|
|
public class NotificationManager: NSObject, UNUserNotificationCenterDelegate, ObservableObject {
|
|
private let notificationCenter = UNUserNotificationCenter.current()
|
|
|
|
@Published var notificationStatus = NotificationPermissionPromptStatus.unknown
|
|
|
|
public override init() {
|
|
super.init()
|
|
loadNotificationStatus()
|
|
|
|
notificationCenter.delegate = self
|
|
}
|
|
|
|
public func loadNotificationStatus() {
|
|
UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { [weak self] (settings) in
|
|
let status = NotificationManager.systemPromptStatusFromSettings(settings)
|
|
self?.notificationStatus = status
|
|
})
|
|
}
|
|
|
|
private class func systemPromptStatusFromSettings(_ settings: UNNotificationSettings) -> NotificationPermissionPromptStatus {
|
|
switch settings.authorizationStatus {
|
|
case .notDetermined:
|
|
return .notShown
|
|
case .authorized, .provisional:
|
|
return .shownAndAccepted
|
|
case .denied:
|
|
return .shownAndDenied
|
|
@unknown default:
|
|
return .unknown
|
|
}
|
|
}
|
|
|
|
public func requestAccess() {
|
|
|
|
notificationCenter.requestAuthorization(options: [.alert, .sound, .badge]) { [weak self] granted, error in
|
|
DispatchQueue.main.async {
|
|
if let error = error {
|
|
// Handle the error here.
|
|
Logger.appState.error("Error requesting notification accesss: \(error.legibleLocalizedDescription)")
|
|
} else {
|
|
Logger.appState.log("User has \(granted ? "Granted" : "NOT GRANTED") notification permission")
|
|
}
|
|
self?.loadNotificationStatus()
|
|
}
|
|
}
|
|
}
|
|
|
|
func scheduleNotification(title: String?, body: String, category: XcodesNotificationCategory) {
|
|
|
|
let content = UNMutableNotificationContent()
|
|
if let title = title {
|
|
content.title = title
|
|
}
|
|
content.body = body
|
|
content.sound = .default
|
|
content.categoryIdentifier = category.rawValue
|
|
|
|
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.3, repeats: false)
|
|
let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger)
|
|
notificationCenter.add(request)
|
|
}
|
|
|
|
// MARK: UNUserNotificationCenterDelegate
|
|
|
|
public func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
|
|
completionHandler( [.banner, .badge, .sound])
|
|
}
|
|
}
|
|
|