Created
February 23, 2023 06:20
-
-
Save m-usmansaeed/0775edc2380b93146d15169c1f144fb2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // 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 | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // 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