Skip to content

Instantly share code, notes, and snippets.

@erenkabakci
Last active May 2, 2023 22:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erenkabakci/e1460010c63e698956a6aaf9350525eb to your computer and use it in GitHub Desktop.
Save erenkabakci/e1460010c63e698956a6aaf9350525eb to your computer and use it in GitHub Desktop.
UserNotificationsHandling
//
// UserNotificationsHandling.swift
//
// Copyright © 2023 Eren Kabakci. All rights reserved.
//
import UserNotifications
import AppKit
// Generic local notifications API for any consumer to use
protocol UserNotificationsHandling {
func promptAuthorization()
func getNotificationSettings(completion: @escaping (_ enabled: Bool) -> Void)
func schedule(title: String,
body: String,
metaData: UserNotificationMetadata?,
completion: @escaping (Result<Void, Error>) -> Void)
func removeAllPendingNotificationRequests()
func removeAllDeliveredNotifications()
}
extension UNUserNotificationCenter: UserNotificationsHandling {
func getNotificationSettings(completion: @escaping (_ enabled: Bool) -> Void) {
getNotificationSettings(completionHandler: { settings in
completion(settings.authorizationStatus == .authorized ? true : false)
})
}
func promptAuthorization() {
requestAuthorization(options: [.alert, .badge, .sound]) { _,_ in }
}
func schedule(title: String,
body: String,
metaData: UserNotificationMetadata?,
completion: @escaping (Result<Void, Error>) -> Void) {
promptAuthorization()
getNotificationSettings { [weak self] notificationSettings in
let correctAlertStyle = notificationSettings.alertStyle == UNAlertStyle.alert || notificationSettings.alertStyle == UNAlertStyle.banner
let notificationsEnabled = notificationSettings.authorizationStatus != UNAuthorizationStatus.denied
guard correctAlertStyle, notificationsEnabled else {
if metaData == nil {
DispatchQueue.main.async {
let userAlert = NSAlert()
userAlert.messageText = title
userAlert.informativeText = body
userAlert.alertStyle = NSAlert.Style.informational
userAlert.addButton(withTitle: "OK")
userAlert.runModal()
}
}
return
}
let content = UNMutableNotificationContent()
content.title = title
content.body = body
if let metaData {
content.threadIdentifier = metaData.threadIdentifier
content.categoryIdentifier = metaData.categoryIdentifier
content.sound = metaData.sound
content.userInfo = metaData.userInfo
}
let request = UNNotificationRequest(
identifier: metaData?.identifier ?? UUID().uuidString,
content: content,
trigger: metaData?.trigger
)
self?.add(request) { error in
if let error = error {
completion(.failure(error))
} else {
completion(.success(()))
}
}
}
}
}
struct UserNotificationMetadata {
let identifier: String?
let trigger: UNNotificationTrigger?
let categoryIdentifier: String
let sound: UNNotificationSound
let userInfo: [String: String]
let threadIdentifier: String
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment