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

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

iOS 10+, Swift 3+:

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

EDIT:

Foreground alerts are now possible in iOS 10! Please see this answer.

For iOS 9 and below:

It does not seem to be possible to show the stock iOS notification alert when your app is open and in the foreground. Messages.app must be using a private API.

The system does not display any alerts, badge the app’s icon, or play any sounds when the app is already frontmost. - UILocalNotification docs

The UIApplicationDelegate methods will still be called, allowing your app to respond to the local or remote notification:

application:didReceiveLocalNotification:
application:didReceiveRemoteNotification:

However, the stock native iOS notification alert banner UI will not be shown as it is in Apple's Messages.app, which must be using a Private API.

The best you can do is is roll your own alert banner or use an existing framework:

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo 
{    
    // Use a 3rd party toast alert framework to display a banner 
    [self toastAlertFromGithub]
}

I have opened a radar for this behavior here: rdar://22313177