Getting local notifications to show while app is in foreground Swift 3

Apparently this is now possible with ios10 :

optional func userNotificationCenter(_ center: UNUserNotificationCenter, 
                 willPresent notification: UNNotification, 
  withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void)

This answer basically says the tools needed to do it:

  • UITableViewCell With UIWebView Dynamic Height
  • AVFoundation: add text to the CMSampleBufferRef video frame
  • Xcode 8 shows error that provisioning profile doesn't include signing certificate
  • Swift turn a country code into a emoji flag via unicode
  • How to handle push notifications if the application is already running?
  • iOS: How to link App Store link that is being developed
  • Displaying a stock iOS notification banner when your app is open and in the foreground?

    I’m just not really understanding how to put it all together.

    I dont know how important this is, but I’m not able to keep the optional func and xcode wants me to switch it to private.

    I’m trying to show the badge, and the docs provide

    static var badge: UNNotificationPresentationOptions { get }
    

    Little lost here.

    And then I’m assuming if I want to exclude a certain view controller from getting these badges and I’m not using a navigation controller this code I found would work? :
    var window:UIWindow?

    if let viewControllers = window?.rootViewController?.childViewControllers {
    for viewController in viewControllers {
        if viewController.isKindOfClass(MyViewControllerClass) {
            print("Found it!!!")
            }
        }
    }
    

    3 Solutions Collect From Internet About “Getting local notifications to show while app is in foreground Swift 3”

    There is a delegate method to display the notification when the app is open in iOS 10. You have to implement this in order to get the rich notifications working when the app is open.

    extension ViewController:UNUserNotificationCenterDelegate {
    
        //for displaying notification when app is in foreground
        func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    
            //If you don't want to show notification when app is open, do something here else and make a return here. 
            //Even you you don't implement this delegate method, you will not see the notification on the specified controller. So, you have to implement this delegate and make sure the below line execute. i.e. completionHandler.
    
            completionHandler([.alert,.badge])
        }
    
        // For handling tap and user actions
        func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
            switch response.actionIdentifier {
            case "action1":
                print("Action First Tapped")
            case "action2":
                print("Action Second Tapped")
            default:
                break
            }
            completionHandler()
        }
    
    }
    

    In order to schedule a notification in iOS 10 and providing a badge

    override func viewDidLoad() {
        super.viewDidLoad()
    
        // set UNUserNotificationCenter delegate to self
        UNUserNotificationCenter.current().delegate = self
        scheduleNotifications()
    }
    
    func scheduleNotifications() {
    
        let content = UNMutableNotificationContent()
        let requestIdentifier = "rajanNotification"
    
        content.badge = 1
        content.title = "This is a rich notification"
        content.subtitle = "Hello there, I am Rajan Maheshwari"
        content.body = "Hello body"
        content.categoryIdentifier = "actionCategory"
        content.sound = UNNotificationSound.default()
    
        // If you want to attach any image to show in local notification
        let url = Bundle.main.url(forResource: "notificationImage", withExtension: ".jpg")
        do {
            let attachment = try? UNNotificationAttachment(identifier: requestIdentifier, url: url!, options: nil)
            content.attachments = [attachment!]
        }      
    
        let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 3.0, repeats: false)
    
        let request = UNNotificationRequest(identifier: requestIdentifier, content: content, trigger: trigger)
        UNUserNotificationCenter.current().add(request) { (error:Error?) in
    
            if error != nil {
                print(error?.localizedDescription)
            }     
            print("Notification Register Success")
        }
    }
    

    In order to register in AppDelegate we have to write this piece of code in didFinishLaunchingWithOptions

     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            // Override point for customization after application launch.
            registerForRichNotifications()
            return true
        }
    

    I have defined actions also here. You may skip them

    func registerForRichNotifications() {
    
           UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.badge,.sound]) { (granted:Bool, error:Error?) in
                if error != nil {
                    print(error?.localizedDescription)
                }
                if granted {
                    print("Permission granted")
                } else {
                    print("Permission not granted")
                }
            }
    
            //actions defination
            let action1 = UNNotificationAction(identifier: "action1", title: "Action First", options: [.foreground])
            let action2 = UNNotificationAction(identifier: "action2", title: "Action Second", options: [.foreground])
    
            let category = UNNotificationCategory(identifier: "actionCategory", actions: [action1,action2], intentIdentifiers: [], options: [])
    
            UNUserNotificationCenter.current().setNotificationCategories([category])
    
        }
    

    Check this link for more details
    https://www.youtube.com/watch?v=Svul_gCtzck

    Github Sample
    https://github.com/kenechilearnscode/UserNotificationsTutorial

    Here is the output

    enter image description here

    enter image description here

    Key to getting your notifications to show up while your app is in the foreground is also setting:

    content.setValue(true, forKey: "shouldAlwaysAlertWhileAppIsForeground")
    

    in your UNNotificationRequest. As for the rest, see the excellent answer by Rajan Maheshwari.

    Swift 3 | iOS 10+

    Assuming you know how to schedule a local notification:

    func scheduleLocalNotification(forDate notificationDate: Date) {
    
        let calendar = Calendar.init(identifier: .gregorian)
    
        let requestId: String = "123"
        let title: String = "Notification Title"
        let body: String = "Notification Body"
    
        // construct notification content
        let content = UNMutableNotificationContent()
        content.title = NSString.localizedUserNotificationString(forKey: title, arguments: nil)
        content.body = NSString.localizedUserNotificationString(forKey: body, arguments: nil)
        content.sound = UNNotificationSound.default()
        content.badge = 1
        content.userInfo = [
            "key1": "value1"
        ]
    
        // configure trigger
        let calendarComponents: [Calendar.Component] = [.year, .month, .day, .hour, .minute]
        let dateComponents = calendar.dateComponents(calendarComponents, from: notificationDate)
        let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false)
    
        // create the request
        let request = UNNotificationRequest.init(identifier: requestId, content: content, trigger: trigger)
    
        // schedule notification
        UNUserNotificationCenter.current().add(request) { (error: Error?) in
            if let error = error {
                // handle error
            }
        }
    }
    

    You need to make your AppDelegate implement the UNUserNotificationCenterDelegate protocol, and set it as the notification center’s delegate with UNUserNotificationCenter.current().delegate = self.

    // AppDelegate.swift
    
    import UIKit
    import UserNotifications
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
    
        func application(_ application: UIApplication, didFinishLaunchingWithOptions 
            launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    
            // set app delegate as notification center delegate
            UNUserNotificationCenter.current().delegate = self
        }
    }
    
    extension AppDelegate: UNUserNotificationCenterDelegate {
    
        // called when user interacts with notification (app not running in foreground)
        func userNotificationCenter(_ center: UNUserNotificationCenter, 
            didReceive response: UNNotificationResponse, withCompletionHandler 
            completionHandler: @escaping () -> Void) {
    
            // do something with the notification
            print(response.notification.request.content.userInfo)
    
            // the docs say you should execute this asap
            return completionHandler()
        }
    
        // called if app is running in foreground
        func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent 
            notification: UNNotification, withCompletionHandler completionHandler: 
            @escaping (UNNotificationPresentationOptions) -> Void) {
    
            // show alert while app is running in foreground
            return completionHandler(UNNotificationPresentationOptions.alert)
        }
    }
    

    Now your local notifications will appear when your app is in the foreground.

    See the UNUserNotificationCenterDelegate docs for reference.