235

I am using push notification service in my app. When app is in background I am able to see notification on notification screen(screen shown when we swipe down from top of iOS device). But if application is in foreground the delegate method

- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo

is getting called but notification is not displayed in notification screen.

I want to show notification on notification screen independent of whether app is in background or foreground. I am tired by searching for a solution. Any help is greatly appreciated.

Ved Rauniyar
  • 1,539
  • 14
  • 21
Ab'initio
  • 5,368
  • 4
  • 28
  • 40
  • 42
    Apple [says](https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/NotificationCenter.html): **If you receive local or remote notifications while your app is running in the foreground, you’re responsible for passing the information to your users in an app-specific way.** – Lauri Lehmijoki Mar 18 '16 at 06:23
  • 2
    Some up-to-date (oct "16) apple links: [here](https://developer.apple.com/ios/human-interface-guidelines/features/notifications/), [there](https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/Introduction.html) and [there](https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/WhatAreRemoteNotif.html#//apple_ref/doc/uid/TP40008194-CH102-SW1) – azmeuk Oct 17 '16 at 14:38
  • 1
    isn't foreground support of push notification for iOS 9.3 and less? – Anurag Sharma Apr 10 '17 at 11:08
  • @Lauri Lehmijoki link? I didn't find that on official website – Vyachaslav Gerchicov Jul 10 '18 at 15:14
  • 2
    I am facing the same problem in ionic... – Sayed Mohd Ali Nov 27 '19 at 08:43
  • You may also find the answer here: https://iosarchitect.com/show-push-notifications-when-app-running-in-foreground-ios-swift/ – Keshu R. Oct 11 '20 at 09:46
  • 4
    Latest link to Apple's documentation regarding User Notifications is now [here (general)](https://developer.apple.com/documentation/usernotifications) and [here (foreground notifications)](https://developer.apple.com/documentation/usernotifications/handling_notifications_and_notification-related_actions). – lukemmtt Jan 02 '21 at 13:45

20 Answers20

251

For displaying banner message while app is in foreground, use the following method.

iOS 10, Swift 3/4 :

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

iOS 10, Swift 2.3 :

@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void)
{
    //Handle the notification
    completionHandler(
       [UNNotificationPresentationOptions.Alert,
        UNNotificationPresentationOptions.Sound,
        UNNotificationPresentationOptions.Badge])
}

You must also register your app delegate as the delegate for the notifications center:

import UserNotifications

// snip!

class AppDelegate : UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate

// snip!

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

      // set the delegate in didFinishLaunchingWithOptions
      UNUserNotificationCenter.current().delegate = self
      ...
   }
Tiago Mendes
  • 4,572
  • 1
  • 29
  • 35
chengsam
  • 7,315
  • 6
  • 30
  • 38
  • When this method is called? – Uma Madhavi Dec 19 '16 at 10:02
  • Please guide me i am struck up displaying notification from top when my app background or foreground.Since 2 weeks i am working with push notifications.I am able receive msg from server. – Uma Madhavi Dec 19 '16 at 10:04
  • @UmaMadhavi Can you receive push notifications? – chengsam Dec 20 '16 at 05:10
  • when i run my app i am getting message from fcm server. But in background or foreground i am not getting..Please check my code http://stackoverflow.com/questions/41198651/xcode-8-1-push-notifications-in-swift-2-3-with-firebase-integration-not-getting – Uma Madhavi Dec 20 '16 at 05:16
  • This kind of information i get when i launch my app . %@ [from: 730307127978, itemId: 5858bd87e4b0d0e761b1acb6, viewed: false, createdTS: 1482210690908, notificationToName: Uma Madhavi, notificationType: ISUPPORT_CREATED, collapse_key: do_not_collapse, actionByName: Uma Madhavi, notificationTo: 572c5ae7e4b08bce2f9641a7, actionBy: 572c5ae7e4b08bce2f9641a7] – Uma Madhavi Dec 20 '16 at 05:34
  • This is working fine for iOS 10.2, Thanks for the code. – Anil shukla Feb 20 '17 at 13:57
  • 24
    Don't forget to set the Notification Center delegate as app delegate: `UNUserNotificationsCenter.current().delegate = self` in application didFinishLaunchingWithOptions – Achintya Ashok Jun 07 '17 at 01:07
  • @chengsam it is not working in ios 8 for foreground state – Dilip Tiwari Sep 29 '17 at 07:08
  • @DilipTiwari It's for iOS 10+. – chengsam Sep 29 '17 at 08:07
  • i know but i need in ios 8.0 @chengsam – Dilip Tiwari Sep 29 '17 at 09:24
  • @DilipTiwari For ios < 10.0, you need to make your own UI for it, e.g., a popup, as UNUserNotificationCenter is not available for iOS 9, 8, etc. – auspicious99 Jul 11 '18 at 17:32
  • 3
    For those who still struggling, its UNUserNotificationCenter not UNUserNotificationsCenter with 's' before center – Raj Jul 25 '18 at 02:20
  • Thanks! This works even for notifications added via `UNUserNotificationCenter.current().add()` – Senseful Aug 20 '18 at 20:02
  • @chengsam how can i do it in objective c `import UserNotifications // snip! class AppDelegate : UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate // snip! // set the delegate in didFinishLaunchingWithOptions UNUserNotificationCenter.current().delegate = self` – iOS Developer Oct 24 '18 at 08:01
  • 1
    @Achintya Ashok there is a typo on your comment, you added in 's' and Notification, it should be UNUserNotificationCenter.current().delegate = self – Matthew Usdin Apr 25 '19 at 10:01
  • it is working for me too but it dismisses after few sec.. is it possible to keep it presented until the user clicks on it ? @chengsam – Niib Fouda Mar 31 '20 at 12:51
  • This is how you should be handling the notification to show alert when app is open. This should be marked as answer. – Vipin Johney Jul 23 '20 at 15:36
61

Below code will be work for you :

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo  {
    application.applicationIconBadgeNumber = 0;             
    //self.textView.text = [userInfo description];
    // We can determine whether an application is launched as a result of the user tapping the action
    // button or whether the notification was delivered to the already-running application by examining
    // the application state.

    if (application.applicationState == UIApplicationStateActive) {                
        // Nothing to do if applicationState is Inactive, the iOS already displayed an alert view.                
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Did receive a Remote Notification" message:[NSString stringWithFormat:@"Your App name received this notification while it was running:\n%@",[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]]delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [alertView show];          
    }    
}
Aamir
  • 16,329
  • 10
  • 59
  • 65
Mahesh Peri
  • 1,689
  • 2
  • 14
  • 24
  • This works. A little more info about what it does; when the application is in the foreground, a native UI alert box appears with the notification text within it (the `title` is a slightly larger bolded text, and the `message` is smaller text under that. An 'OK' button to dismiss is at the bottom). The option applicationIconBadgeNumber being set to 0 is to hide the number that appears on top of the app icon in Springboard (for example signifying number of unread messages in a mail app). In this example, I don't know if that option is even needed. – jwinn Oct 06 '17 at 17:47
  • Does this work for both UNnotification AND UILocalNotification? – user6631314 May 09 '18 at 15:18
42

Objective C

enter image description here

For iOS 10 we need integrate willPresentNotification method for show notification banner in foreground.

If app in foreground mode(active)

- (void)userNotificationCenter:(UNUserNotificationCenter* )center willPresentNotification:(UNNotification* )notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
    NSLog( @"Here handle push notification in foreground" ); 
    //For notification Banner - when app in foreground
    
    completionHandler(UNNotificationPresentationOptionAlert);
    
    // Print Notification info
    NSLog(@"Userinfo %@",notification.request.content.userInfo);
}
ksav
  • 20,015
  • 6
  • 46
  • 66
Ashwini Chougale
  • 1,093
  • 10
  • 26
37

For anyone might be interested, I ended up creating a custom view that looks like the system push banner on the top but adds a close button (small blue X) and an option to tap the message for custom action. It also supports the case of more than one notification arrived before the user had time to read/dismiss the old ones (With no limit to how many can pile up...)

Link to GitHub: AGPushNote

The usage is basically on-liner:

[AGPushNoteView showWithNotificationMessage:@"John Doe sent you a message!"];

And it looks like this on iOS7 (iOS6 have an iOS6 look and feel...)

enter image description here

Aviel Gross
  • 9,770
  • 3
  • 52
  • 62
27

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)
}
Abhishek Bedi
  • 5,205
  • 2
  • 36
  • 62
Ab'initio
  • 5,368
  • 4
  • 28
  • 40
  • 86
    I dont think this will help. Local and remote notifications are treated the same and as a result when this local notification fires off and if the app is running then the badge/banner or sound will not be shown/played. – RPM Apr 24 '13 at 22:23
  • my requirement was to show notification in notification view(view appears when swipe from top), and the above solution worked for me..try it yourself...:) – Ab'initio Apr 25 '13 at 03:45
  • Am I right in assuming that this will show the notification banner, but will not leave an entry in the iOS Notification center? – Sean Dec 05 '13 at 21:01
  • 4
    It will also leave an entry in iOS Notification Center – Ab'initio May 06 '14 at 12:50
  • @Ab'initio: just curious, is there a point in using the LocalNotification here? Couln't the same effect be achieved using a plain alert (with the added benefit that the title could be customized as well)? Thank you for the solution though – Rick77 May 26 '14 at 12:00
  • @Rick77 as of iOS 7 that won't show anything when the app is in the foreground, I haven't tested with iOS 6 but I believe it's the same. Of course, that depends on what you have implemented in ```-application:didReceiveLocalNotification:```. With an empty implementation nothing is shown. Maybe Ab'initio forgot to mention his implementation or people are mixing foreground with background. – Fábio Oliveira Jun 12 '14 at 13:50
  • 3
    However I wouldn't launch a local notification when a push notification comes. I would launch a similar behaviour instead like @Rick77 mentioned: showing an alert or some toaster. I guess I don't have to go through the operating system again for something that the operating system is asking me to handle. – Fábio Oliveira Jun 12 '14 at 13:53
  • 3
    This solution is working, as local and remote are handled in the same way, where when app is in foreground, creating a location notification when remote notification comes won't show any thing. Using alert or custom alert is the solution – Hammer Nov 06 '14 at 03:11
  • 19
    This doesn't actually work. From the UILocalNotification docs: `If the app is foremost and visible when the system delivers the notification, the app delegate’s application:didReceiveLocalNotification: is called to process the notification. Use the information in the provided UILocalNotification object to decide what action to take. The system does not display any alerts, badge the app’s icon, or play any sounds when the app is already frontmost.` – Chris Morse Jun 30 '15 at 20:03
  • It's not working. Application screen becomes dark and getting exception like XPC connection interrupted. – Narasimha Nallamsetty Oct 31 '15 at 09:42
  • Is there a way you can get that default "message" from the server? How do you get that message?? If the app is inactive, the message would be visible to the users. If the app is active, how do you get that message as an instance? – coolcool1994 Dec 04 '16 at 18:43
  • It's not working. because remote and local push notification are treating as same. so this will not work – pradeepchauhan_pc Dec 23 '16 at 05:36
23

For Swift 5

1) Confirm the delegate to the AppDelegate with UNUserNotificationCenterDelegate

2) UNUserNotificationCenter.current().delegate = self in didFinishLaunch

3) Implement the below the method in AppDelegate.

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

That's it!

TheTiger
  • 13,264
  • 3
  • 57
  • 82
karthik
  • 251
  • 2
  • 2
  • 1
    .alert is deprecated in iOS14, use .banner and .list instead. https://developer.apple.com/documentation/usernotifications/unnotificationpresentationoptions/3564813-list – blyscuit Mar 02 '22 at 11:15
22

Xcode 10 Swift 4.2

To show Push Notification when your app is in the foreground -

Step 1 : add delegate UNUserNotificationCenterDelegate in AppDelegate class.

class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

Step 2 : Set the UNUserNotificationCenter delegate

let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.delegate = self

Step 3 : This step will allow your app to show Push Notification even when your app is in foreground

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

    }

Step 4 : This step is optional. Check if your app is in the foreground and if it is in foreground then show Local PushNotification.

func application(_ application: UIApplication,didReceiveRemoteNotification userInfo: [AnyHashable: Any],fetchCompletionHandler completionHandler:@escaping (UIBackgroundFetchResult) -> Void) {

        let state : UIApplicationState = application.applicationState
        if (state == .inactive || state == .background) {
            // go to screen relevant to Notification content
            print("background")
        } else {
            // App is in UIApplicationStateActive (running in foreground)
            print("foreground")
            showLocalNotification()
        }
    }

Local Notification function -

fileprivate func showLocalNotification() {

        //creating the notification content
        let content = UNMutableNotificationContent()

        //adding title, subtitle, body and badge
        content.title = "App Update"
        //content.subtitle = "local notification"
        content.body = "New version of app update is available."
        //content.badge = 1
        content.sound = UNNotificationSound.default()

        //getting the notification trigger
        //it will be called after 5 seconds
        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)

        //getting the notification request
        let request = UNNotificationRequest(identifier: "SimplifiedIOSNotification", content: content, trigger: trigger)

        //adding the notification to notification center
        notificationCenter.add(request, withCompletionHandler: nil)
    }
Prashant Gaikwad
  • 3,493
  • 1
  • 24
  • 26
  • 2
    This is a great example of the need to read all the replies to a thread. Earlier threads mention the method, than the delegate and finally this one all three steps you need to make. THANK YOU Prashant for a complete answer! – user3069232 Feb 13 '20 at 16:03
  • Good to know that it helped you. Happy coding – Prashant Gaikwad Feb 14 '20 at 05:31
17

If the application is running in the foreground, iOS won't show a notification banner/alert. That's by design. You have to write some code to deal with the situation of your app receiving a notification while it is in the foreground. You should show the notification in the most appropriate way (for example, adding a badge number to a UITabBar icon, simulating a Notification Center banner, etc.).

Daniel Martín
  • 7,815
  • 1
  • 29
  • 34
  • 1
    but in iOS mail application they have done it, you will get new notification banner/alert while mail app in foreground – Ab'initio Feb 14 '13 at 10:10
  • 3
    @Ab'initio I don't know for sure, but in iOS all applications are not created equal. I suppose the stock Mail app is using some kind of private API that is not available in the public SDK. Or maybe the notification code is making an exception with Apple's Mail app id. – Daniel Martín Feb 14 '13 at 10:25
  • 1
    What?? I am about to have a harpy rage attack. – Josh Jan 12 '17 at 09:32
  • @DanielMartín could u tell me how will i receive a notification in foreground state in iOS 8.0 – Dilip Tiwari Sep 20 '17 at 07:37
  • 18
    Bear in mind that this answer is true **only for iOS 9 and lower**. Since iOS 10, Apple introduced a new API to handle notifications (the `UNUserNotificationCenter ` API). Along with the new API, now **it is possible to show the notifications if the application is in the foreground.** So if you are confused because the different answers in this question, it is because some of the answers are too old, and only describe the behavior for iOS 9 and before, whereas the other ones do not take into account that the `UNUserNotificationCenter ` is only available from iOS 10. – tomacco May 02 '18 at 13:34
9

You can create your own notification that mimics the banner alert.

One way is to create a custom uiview that looks like the banner and can animate and respond to touches. With this in mind you can create even better banners with even more functionality.

Or you can look for an api that does it for you and add them as podfiles to your project.

Here are a couple that I have used:

https://github.com/terryworona/TWMessageBarManager

https://github.com/toursprung/TSMessages

Alex Zavatone
  • 4,106
  • 36
  • 54
marshy101
  • 594
  • 7
  • 19
  • 1
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Robert Mar 28 '14 at 15:15
  • 1
    `TWMessageBarManager` can be easily invoked and used via appdelegate itself as it uses singleton design pattern. Thanks for the links. – Jay Mayu Jul 23 '15 at 06:29
8

Here is the code to receive Push Notification when app in active state (foreground or open). UNUserNotificationCenter documentation

@available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void)
{
     completionHandler([UNNotificationPresentationOptions.Alert,UNNotificationPresentationOptions.Sound,UNNotificationPresentationOptions.Badge])
}

If you need to access userInfo of notification use code: notification.request.content.userInfo

David
  • 3,285
  • 1
  • 37
  • 54
Kavin Kumar Arumugam
  • 1,792
  • 3
  • 28
  • 47
4

Adding that completionHandler line to delegate method solved same problem for me:

//Called when a notification is delivered to a foreground app.
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

completionHandler([.alert, .badge, .sound])
} 
3

For swift 5 to parse PushNotification dictionary

    func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) {
            if application.applicationState == .active {
                if let aps1 = data["aps"] as? NSDictionary {
                    if let dict = aps1["alert"] as? NSDictionary {
                        if let strTitle = dict["title"] as? String , let strBody = dict["body"] as? String {
                            if let topVC = UIApplication.getTopViewController() {
                                //Apply your own logic as per requirement
                                print("strTitle ::\(strTitle) , strBody :: \(strBody)")
                            }
                        }
                    }
                }
            }
        }

To fetch top viewController on which we show topBanner

extension UIApplication {

    class func getTopViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {

        if let nav = base as? UINavigationController {
            return getTopViewController(base: nav.visibleViewController)

        } else if let tab = base as? UITabBarController, let selected = tab.selectedViewController {
            return getTopViewController(base: selected)

        } else if let presented = base?.presentedViewController {
            return getTopViewController(base: presented)
        }
        return base
    }
}
Hardik Thakkar
  • 15,269
  • 2
  • 94
  • 81
2

In your app delegate use bellow code

import UIKit
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
 var currentToken: String?
 var window: UIWindow?
 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        application.registerForRemoteNotifications()
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in

            // Enable or disable features based on authorization.
            if granted == true
            {
                print("Allow")
                UIApplication.shared.registerForRemoteNotifications()
            }
            else
            {
                print("Don't Allow")
            }
        }
        UNUserNotificationCenter.current().delegate = self

        return true
    }
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data){
        let tokenParts = deviceToken.map { data -> String in
            return String(format: "%02.2hhx", data)
        }
        let token = tokenParts.joined()
        currentToken = token  //get device token to delegate variable

    }
 public class var shared: AppDelegate {
        return UIApplication.shared.delegate as! AppDelegate
    }
 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
         completionHandler([.alert, .badge, .sound])
    }
}
Varun Naharia
  • 5,318
  • 10
  • 50
  • 84
2

iOS 14+

Follow this answer with one difference, .alert is deprecated, use .banner:

class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil
    ) -> Bool {
        UNUserNotificationCenter.current().delegate = self

        return true
    }

    func userNotificationCenter(
        _ center: UNUserNotificationCenter,
        willPresent notification: UNNotification,
        withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
    ) {
        completionHandler([.banner, .badge, .sound])
    }
}
Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
2

Works in iOS 14+ as well, no need to handle any alerts or views manually simply let iOS do its thing

Inside where we reive the notification replace with below code

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])
      }
    }
  }

Main thing to lookout for is not to use sound while in forground it wont show banner

Asaf Pinhassi
  • 15,177
  • 12
  • 106
  • 130
1

Best Approach for this is to add UNUserNotificationCenterDelegate in AppDelegate by using extension AppDelegate: UNUserNotificationCenterDelegate That extension tells the app to be able to get notification when in use

And implement this method

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

This method will be called on the delegate only if the application is in the Foreground.

So The final Implementation:

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

And To call this you must set the delegate in AppDelegate in didFinishLaunchingWithOptions add this line

UNUserNotificationCenter.current().delegate = self

You can modify

completionHandler(.alert) 

with

completionHandler([.alert, .badge, .sound]))
JhonnyTawk
  • 834
  • 11
  • 23
1

100% working tested

First import

import UserNotifications

then add delegate in class

UNUserNotificationCenterDelegate


class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate

Following method is responsible while app is open and notifcation comes.

willPresent

   @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
            let content = notification.request.content

           let alertVC = UIAlertController.init(title: title, message: body, preferredStyle: .alert)

            alertVC.addAction(UIAlertAction.init(title: appLan_share.Ok_txt, style: .default, handler: {
                _ in
                   //handle tap here or navigate somewhere…..                
            }))

            vc?.present(alertVC, animated: true, completion: nil)

            print("notification Data: \(content.userInfo.values)")
                completionHandler([.alert, .sound])



}

you can also handle application state by checking current application state.

Additionally if your app is not running then following method is responsible for handling push notification

didReceive

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        let userInfo = response.notification.request.content.userInfo
        let aps = userInfo["aps"] as? [String: Any]
        let alert = aps?["alert"] as? [String: String]

}
Mr.Javed Multani
  • 12,549
  • 4
  • 53
  • 52
0

As mentioned above, you should use UserNotification.framework to achieve this. But for my purposes I have to show it in app anyway and wanted to have iOS 11 style, so I've created a small helper view, maybe would be useful for someone.

GitHub iOS 11 Push Notification View.

Orest Savchak
  • 4,529
  • 1
  • 18
  • 27
-2

If your application is in foreground state, it means you are currently using the same app. So there is no need to show notification on the top generally.

But still if you want to show notification in that case you have to create your custom Alert View or Custom View like Toast or something else to show to the user that you have got a notification.

You can also show a badge on the top if you have such kind of feature in your app.

SHIV
  • 66
  • 1
-3

As @Danial Martine said iOS won't show a notification banner/alert. That's by design. But if really have to do it then there is one way . I have also achieve this by same.

1.Download the parse frame work from Parse FrameWork

2.Import #import <Parse/Parse.h>

3.Add following code to your didReceiveRemoteNotification Method

 - (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    [PFPush handlePush:userInfo];
}

PFPush will take care how to handle the remote notification . If App is in foreground this shows the alert otherwise it shows the notification at the top.

V-Xtreme
  • 7,230
  • 9
  • 39
  • 79