Skip to content

Instantly share code, notes, and snippets.

@m-usmansaeed
Created February 23, 2023 06:20
Show Gist options
  • Select an option

  • Save m-usmansaeed/0775edc2380b93146d15169c1f144fb2 to your computer and use it in GitHub Desktop.

Select an option

Save m-usmansaeed/0775edc2380b93146d15169c1f144fb2 to your computer and use it in GitHub Desktop.
//
// NotificationScheduler.swift
// LocationNotifier
//
import UIKit
import UserNotifications
protocol NotificationSchedulerDelegate: UNUserNotificationCenterDelegate {
/// Called when the user has denied the notification permission prompt.
func notificationPermissionDenied()
/// Called when the notification request completed.
///
/// - Parameter error: Optional error when trying to add the notification.
func notificationScheduled(error: Error?)
}
struct NotificationInfo {
// Identifiers
let notificationId: String
// Notification
let title: String
let body: String
let data: [String: Any]?
}
class NotificationScheduler: NSObject, UNUserNotificationCenterDelegate {
// MARK: - Public Properties
weak var delegate: NotificationSchedulerDelegate? {
didSet {
UNUserNotificationCenter.current().delegate = self
}
}
// MARK: - Private Properties
// MARK: - Public Functions
/// Request a geo location notification with optional data.
///
/// - Parameter data: Data that will be sent with the notification.
func requestNotification(with notificationInfo: NotificationInfo) {
askForNotificationPermissions(notificationInfo: notificationInfo)
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
if (UIApplication.shared.applicationState == .inactive || UIApplication.shared.applicationState == .background) {
if #available(iOS 14.0, *) {
completionHandler([[.banner, .sound]])
} else {
completionHandler([.alert, .sound])
}
} else {
if #available(iOS 14.0, *) {
completionHandler([[.banner]])
} else {
completionHandler([.alert])
}
}
// completionHandler([.alert, .sound, .badge])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
print(response.notification.request.content.userInfo)
completionHandler()
}
}
// MARK: - Private Functions
private extension NotificationScheduler {
func askForNotificationPermissions(notificationInfo: NotificationInfo) {
UNUserNotificationCenter.current().requestAuthorization(
options: [.alert, .sound, .badge],
completionHandler: { [weak self] granted, _ in
guard granted else {
DispatchQueue.main.async {
self?.delegate?.notificationPermissionDenied()
}
return
}
self?.requestNotification(notificationInfo: notificationInfo)
})
}
func requestNotification(notificationInfo: NotificationInfo) {
let notification = notificationContent(notificationInfo: notificationInfo)
let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 5, repeats: false)
let request = UNNotificationRequest(identifier: notificationInfo.notificationId,
content: notification,
trigger: trigger)
UNUserNotificationCenter.current().add(request) { [weak self] (error) in
DispatchQueue.main.async {
self?.delegate?.notificationScheduled(error: error)
}
}
}
func notificationContent(notificationInfo: NotificationInfo) -> UNMutableNotificationContent {
let notification = UNMutableNotificationContent()
notification.title = notificationInfo.title
notification.body = notificationInfo.body
notification.sound = UNNotificationSound.default
if let data = notificationInfo.data {
notification.userInfo = data
}
return notification
}
}
//
// ViewController.swift
// LocationNotifier
//
import UIKit
import UserNotifications
class ViewController: UIViewController {
private let locationNotificationScheduler = NotificationScheduler()
override func viewDidLoad() {
super.viewDidLoad()
locationNotificationScheduler.delegate = self
}
/// Center button to schedule a notification.
///
/// - Parameter sender: Button sender.
@IBAction func scheduleLocationNotification(_ sender: Any) {
let notificationInfo = NotificationInfo(notificationId: "notification_id",
title: "Alert!",
body: "This is test notification.",
data: ["userInfo": "extra info"])
locationNotificationScheduler.requestNotification(with: notificationInfo)
}
}
extension ViewController: NotificationSchedulerDelegate {
func notificationPermissionDenied() {
let message = "The notification permission was not authorized. Please enable it in Settings to continue."
presentSettingsAlert(message: message)
}
func notificationScheduled(error: Error?) {
}
private func presentSettingsAlert(message: String) {
let alertController = UIAlertController(title: "Permissions Denied!",
message: message,
preferredStyle: .alert)
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
let settingsAction = UIAlertAction(title: "Settings", style: .default) { (alertAction) in
if let appSettings = URL(string: UIApplication.openSettingsURLString) {
UIApplication.shared.open(appSettings)
}
}
alertController.addAction(cancelAction)
alertController.addAction(settingsAction)
present(alertController, animated: true)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment