Displaying a Stock iOS Notification Banner When Your App Is Open and in the Foreground

Displaying a stock iOS notification banner when your app is open and in the foreground?

iOS 10 adds the UNUserNotificationCenterDelegate protocol for handling notifications while your app is in the foreground.

The UNUserNotificationCenterDelegate protocol defines methods for receiving notifications and for handling actions. When your app is in the foreground, arriving notifications are delivered to your delegate object instead of displayed automatically using the system interfaces.

Swift:

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

Objective-C:

- (void)userNotificationCenter:(UNUserNotificationCenter *)center 
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler;

The UNNotificationPresentationOptions flags allow you to specify UNNotificationPresentationOptionAlert to display an alert using the text provided by the notification.

This is key as it allows you to display the alert while your app is open and in the foreground, which is new for iOS 10.



Sample code:

class AppDelegate: UIResponder, UIApplicationDelegate {

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

// Set UNUserNotificationCenterDelegate
UNUserNotificationCenter.current().delegate = self

return true
}

}

// Conform to UNUserNotificationCenterDelegate
extension AppDelegate: UNUserNotificationCenterDelegate {

func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
{
completionHandler(.alert)
}

}

Get push notification while App in foreground iOS

If the application is running in the foreground, iOS won't show a notification banner/alert. That's by design. But we can achieve it by using UILocalNotification as follows

  • Check whether application is in active state on receiving a remote

    notification. If in active state fire a UILocalNotification.

    if (application.applicationState == UIApplicationStateActive ) {

    UILocalNotification *localNotification = [[UILocalNotification alloc] init];
    localNotification.userInfo = userInfo;
    localNotification.soundName = UILocalNotificationDefaultSoundName;
    localNotification.alertBody = message;
    localNotification.fireDate = [NSDate date];
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
    }

SWIFT:

if application.applicationState == .active {
var localNotification = UILocalNotification()
localNotification.userInfo = userInfo
localNotification.soundName = UILocalNotificationDefaultSoundName
localNotification.alertBody = message
localNotification.fireDate = Date()
UIApplication.shared.scheduleLocalNotification(localNotification)
}

Show notification in iOS app While app in foreground / Active in swift 3

If the application is running in the foreground, iOS won't show a notification banner/alert. You have to write some code to deal with the situation of your app receiving a notification while it is in the foreground.

Or you can use popular Third party library : github.com/bryx-inc/BRYXBanner

Use it like below

import BRYXBanner // import in your class 

// Put this code where you are getting notification
let banner = Banner(title: "title", subtitle: "subtitle", image: UIImage(named: "addContact"), backgroundColor: UIColor(red:137.0/255.0, green:172.0/255.0, blue:2.0/255.0, alpha:1.000))
banner.dismissesOnTap = true
banner.show(duration: 1.0)

But if You are using iOS 10.0+ then you can approach goal for displaying banner message while app is in foreground, use the following method.

 // This method will be called when app received push notifications in foreground for iOS 10+
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .badge, .sound])
}

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, .sound])
}

// 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 ?? "some unknown error")
}
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])

}

If you want that your notification banner should be shown everywhere in the entire application, then you can write the delegate of UNUserNotificationDelegate in AppDelegate and make the UNUserNotificationCenter current delegate to AppDelegate

extension AppDelegate: UNUserNotificationCenterDelegate {

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
print(response.notification.request.content.userInfo)
completionHandler()
}

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .badge, .sound])
}
}

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

Sample Image


Sample Image

Is it possible display a banner for ios when receiving push notification while app is in foreground?

  • This is not a limitation of Titanium.
  • Apple doesn't allow to show notification banner when app is in foreground.
  • All you can do is to create and animate a manual view when your Push callback is called in foreground state.

How to show local notification when app is foreground

#import 
#define SYSTEM_VERSION_GRATERTHAN_OR_EQUALTO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

//interface
@interface AppDelegate : UIResponder

@end

//implementation
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
[self registerForRemoteNotifications];
return YES;
}

- (void)registerForRemoteNotifications {
if(SYSTEM_VERSION_GRATERTHAN_OR_EQUALTO(@"10.0")){
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error){
if(!error){
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
}];
}
else {
// Code for old versions
}
}

////...........Handling delegate methods for UserNotifications........
//Called when a notification is delivered to a foreground app.

-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
NSLog(@"User Info : %@",notification.request.content.userInfo);
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}

//Called to let your app know which action was selected by the user for a given notification.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler{
NSLog(@"User Info : %@",response.notification.request.content.userInfo);
completionHandler();
}

May this will help you. :)



Related Topics



Leave a reply



Submit