iOS Swift Local Notifications - Register, Create and Respond example

With local notifications, your app configures the notification details right inside the app and then passes those details to the system, which then handles the delivery of the notification when your app is not in the foreground. With local notification you don't need a server to push data to Apple Push Notification service.

iOS Swift Local Notifications - Register
iOS Swift Local Notifications - Create

Step 1: Request Authorization to annoy the user in your App Delegate

Just remember that the system saves the user’s response so any calls to this method during subsequent launches do not prompt the user again. Also the user can change the authorized interaction types for your app at any time afterwards using system settings. You can call the getNotificationSettings method of UNUserNotificationCenter to find the current settings.

Notification categories define the types of notifications that your app supports and communicate to the system how you want a notification to be presented. You use categories to associate custom actions with a notification and to specify options for how to handle notifications of that type.

import UIKit
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
        [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        let center = UNUserNotificationCenter.current()
        
        // Request permission to display alerts and play sounds.
        center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
            // Enable or disable features based on authorization.
            if granted {
                print("Notifications permission granted by the User.")
            }
            else {
                print("Notifications permission denied by the User.")
            }
        }
        
        //Catch all Category
        let generalCategory = UNNotificationCategory(identifier: "GENERAL",
                                                     actions: [],
                                                     intentIdentifiers: [],
                                                     options: .customDismissAction)
        
        //TENNISALERT Category
        let acceptAction = UNNotificationAction(identifier: "accept",
                                                title: "Accept", options: .foreground)
        let declineAction = UNNotificationAction(identifier: "decline",
                                                title: "Decline", options: .destructive)
        let myAlertCategory = UNNotificationCategory(identifier: "TENNIS_ALERT",
                                                     actions: [acceptAction, declineAction],
                                                     intentIdentifiers: [], options:
                                                    UNNotificationCategoryOptions(rawValue: 0))
        
        center.setNotificationCategories([generalCategory, myAlertCategory])
        
        let mainStoryboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let mainViewController = mainStoryboard.instantiateInitialViewController()
        let navigationController = UINavigationController(rootViewController: mainViewController!)
        
        //Customize Navigation Bar
        let navigationBarAppearance = navigationController.navigationBar
        navigationBarAppearance.tintColor = UIColor.black
        navigationBarAppearance.barTintColor = UIColor.lightGray
        let attributes = [
            NSAttributedString.Key.foregroundColor: UIColor.black,
            NSAttributedString.Key.font: UIFont(name: "Georgia-Bold", size: 24)!
        ]
        navigationBarAppearance.titleTextAttributes = attributes
        navigationBarAppearance.isTranslucent = false
        
        self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window?.rootViewController = navigationController
        self.window?.makeKeyAndVisible()
        
        return true
    }
    
    func applicationWillResignActive(_ application: UIApplication) {
    
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
    }

    func applicationWillTerminate(_ application: UIApplication) {
    }


}

Step 2: Send Notification and Respond to User Action

Scheduling a local notification requires just three simple steps:
  • Prepare the content
  • Add a trigger when the notification should be fired
  • Schedule it for delivery
Please note: Apps behave differently in background and foreground states whenever a notification is delivered. When your app is not running or is in the background, the system automatically delivers local and remote notifications using the interactions you specified. If the user selects an action, or chooses one of the standard interactions, the system notifies your app of the user’s selection. Your code can then use that selection to perform additional tasks.

If your app is running in the foreground, notifications are delivered directly to your app. You can then decide whether to handle the notification quietly or alert the user.

UserNotifications framework allows you to manage both pending requests and delivered notifications that are still displayed in Notification Center.

  • getPendingNotificationRequests:completionHandler:
  • getDeliveredNotificationRequests:completionHandler:
  • removePendingNotificationRequests:withIdentifiers:
  • removeDeliveredNotifications:withIdentifiers:
  • removeAllPendingNotificationRequests
  • removeAllDeliveredNotifications
iOS Swift Local Notifications - User Action Respond

import UIKit
import UserNotifications
import AVFoundation

class ViewController: UIViewController, UNUserNotificationCenterDelegate {
    
    var dateTextField: UITextField?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //important, otherwise you will not be notified of user actions
        UNUserNotificationCenter.current().delegate = self
        
        self.navigationItem.title = "Main View"
        
        //Create button to send local Notification at 7PM
        let myButton1 = UIButton()
        myButton1.setTitle("Notify me at 11 AM", for: .normal)
        myButton1.setTitleColor(UIColor.blue, for: .normal)
        myButton1.backgroundColor = UIColor.lightGray
        myButton1.frame = CGRect(x: 35, y: 50, width: 300, height: 50)
        
        myButton1.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
        self.view.addSubview(myButton1)
        
        //Create button to send local Notification in 5 minutes
        let myButton2 = UIButton()
        myButton2.setTitle("Notify me in 5 min", for: .normal)
        myButton2.setTitleColor(UIColor.black, for: .normal)
        myButton2.backgroundColor = UIColor.lightGray
        myButton2.frame = CGRect(x: 35, y: 120, width: 300, height: 50)
        
        myButton2.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
        self.view.addSubview(myButton2)
        
        //Create button to cancel the local Notification
        let myButton3 = UIButton()
        myButton3.setTitle("Cancel Notification", for: .normal)
        myButton3.setTitleColor(UIColor.red, for: .normal)
        myButton3.backgroundColor = UIColor.lightGray
        myButton3.frame = CGRect(x: 35, y: 200, width: 300, height: 50)
        
        myButton3.addTarget(self, action: #selector(cancelAction), for: .touchUpInside)
        self.view.addSubview(myButton3)
        
    }
    
    
    @objc func buttonAction(sender: UIButton!) {
        if let buttonTitle = sender.titleLabel?.text {
            print(buttonTitle + " tapped!")
            
            //Lets create the content for the Notification
            let content = UNMutableNotificationContent()
            content.title = NSString.localizedUserNotificationString(
                forKey: "Get Ready!",
                arguments: nil)
            content.body = NSString.localizedUserNotificationString(
                forKey: "You have a Tennis Match in one hour, time to wake up and go.",
                arguments: nil)
            
            // Assign the category (and the associated actions).
            content.categoryIdentifier = "TENNIS_ALERT"
            
            //Sound Notification
            content.sound = UNNotificationSound.default
            
            //Set custom data
            content.userInfo = ["EVENT_TYPE": "Singles", "COURT_TYPE": "Grass"]
            
            //Configure the trigger for a 11am wakeup.
            var dateInfo = DateComponents()
            dateInfo.hour = 11
            dateInfo.minute = 0
            let trigger1 = UNCalendarNotificationTrigger(dateMatching: dateInfo, repeats: false)
            
            //Trigger to wake up in 5 min
            let trigger2 = UNTimeIntervalNotificationTrigger(timeInterval: 5*60, repeats: false)
            
            // Create the request object.
            var request: UNNotificationRequest? = nil
            if buttonTitle == "Notify me at 11 AM" {
                request = UNNotificationRequest(identifier: "TennisAlarm", content: content, trigger: trigger1)
            }
            if buttonTitle == "Notify me in 5 min" {
                request = UNNotificationRequest(identifier: "TennisAlarm", content: content, trigger: trigger2)
                
            }
            
            // Schedule the request.
            let center = UNUserNotificationCenter.current()
            center.getNotificationSettings { (settings) in
                if settings.authorizationStatus != .authorized {
                    print("Notifications not allowed")
                }
                    //allowed
                else {
                    center.add(request!) { (error : Error?) in
                        if let theError = error {
                            print(theError.localizedDescription)
                        }
                    }
                }
            }
            
        }
    }
    
    @objc func cancelAction(sender: UIButton!) {
        
        let center = UNUserNotificationCenter.current()
        print("Cancel Request")
        
        //Remove notifications by Id
        center.removePendingNotificationRequests(withIdentifiers: ["TennisAlarm"])
        
        //Remove all Pending Notifications
        //center.removeAllPendingNotificationRequests()
    }
    
    
    //Gets called when app is in foreground
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        
        //Whatever you would like to do the app now, may be a popup alert...
        print("App is currently in foreground")
        
        // Play a sound.
        completionHandler(UNNotificationPresentationOptions.sound)
    }
    
    //Gets called when app is in background
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) {
        
        // Get the meeting ID from the original notification.
        let notificationInfo = response.notification.request.content.userInfo
        print("Info: \(notificationInfo)")
        
        switch response.notification.request.content.categoryIdentifier {
            
        case "GENERAL":
            break
            
        case "TENNIS_ALERT":
            
            // Retrieve the custom details.
            let eventType = notificationInfo["EVENT_TYPE"] as! String
            let courtType = notificationInfo["COURT_TYPE"] as! String
            
            switch response.actionIdentifier {
            case "accept":
                AudioServicesPlayAlertSound(SystemSoundID(1322))
                print("User Accepts!")
                break
                
            case "decline":
                AudioServicesPlayAlertSound(SystemSoundID(1016))
                print("User Declines!")
                break
                
            default:
                break
            }
            
        default:
            break
        }
        
        // Always call the completion handler when done.
        completionHandler()
    }
    
    
}


Reference: UserNotifications

No comments:

Post a Comment

NO JUNK, Please try to keep this clean and related to the topic at hand.
Comments are for users to ask questions, collaborate or improve on existing.