Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / iOS

iOS 10 User Notification features

4.29/5 (5 votes)
25 Oct 2016CPOL4 min read 17.7K   123  
Quick look on iOS 10 user notification features

Introduction

This project NotificationExample helps developers to have a quick idea on how to use new features introduced in iOS 10 to present flexible and powerful notifications to the users. This article explains how to attach media content, actions and customize the notification UI.

Background

iOS 10 came up with more powerful and flexible local and remote notification features for developers. It introduced two new frameworks.

They are

  • UserNotifications.framework
  • UserNotificationsUI.framework

New features for developers

  • Notification supports video, audio, and images.
  • Notification gets displayed even if App is in foreground
  • Add actions to notification
  • Enable quick reply text
  • GIF image support
  • Customized User Interface for notification

Using the code

Let us create a local notification using new features in iOS 10.

In Xcode, go to build phases and add UserNotifications.framework and UserNotificationsUI.frameworks

#import <UserNotifications/UserNotifications.h> 

Get notification when App is in foreground

extend UNUserNotificationCenterDelegate protocol in your .h/App delegate file and implement willPresentNotification delegate method by executing UNNotificationPresentationOptionAlert in the completion handler.

- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0){ 

    completionHandler(UNNotificationPresentationOptionAlert);

}

Registration for Notification Service

It is mandatory for both local and remote notification

@property(strong,nonatomic) UNUserNotificationCenter* notiCenter;

Add above property in your class extension

// Getting current notification center object and ask for notification authorization from user

    _notiCenter = [UNUserNotificationCenter currentNotificationCenter];

    _notiCenter.delegate=self;

    [_notiCenter  requestAuthorizationWithOptions:(UNAuthorizationOptionAlert + UNAuthorizationOptionSound) completionHandler:^(BOOL granted, NSError * _Nullable error) {

        if(granted)
        {
            [_notiCenter setDelegate:self];

            [self generateTimerBasedNotification];

            [self generateLocationBasedNotification];
        }
        //Enable or disable features based on authorization.
    }];

We can also read notification settings value programmatically in iOS 10 using the API class UNUserNotificationCenter

// Read the notification setting, set by user

    [_notiCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
       if(settings.soundSetting==UNNotificationSettingEnabled)
        {
            NSLog(@"Sound Notification is Enabled");
        }
        else
        {
            NSLog(@"Sound Notification is Disabled");
        }
        if(settings.alertSetting==UNNotificationSettingEnabled)
        {
            NSLog(@"Alert Notification is Enabled");
        }
        else
        {
            NSLog(@"Alert Notification is Disabled");
        }
        if(settings.badgeSetting==UNNotificationSettingEnabled)
        {
            NSLog(@"Badge is Enabled");
        }
        else
        {
            NSLog(@"Badge is Disabled");
        }
    }];

Let us have a look at 2 App extensions newly added in iOS 10 for notification.

  • Notification Service

  • Notification Content

Notification Service Extension

It runs in the background to download any URL, which is specified in the remote notification or replace any content of remote notification before it is displayed to the user.

Go to file->New->Target select Notification Service Extension

After adding the target, NotificationService.h ,NotificationService.m and info.plist files will be created.

NotificationService class derived from UNNotificationServiceExtension, this base class has only 2 messages and Notification Service works only with remote notification.

(void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent *contentToDeliver))contentHandler;

Use above delegate method to download URL content mentioned in your remote notification to display it to user

(void)serviceExtensionTimeWillExpire;

If your App can’t complete the content download within the given time (time between when the device received remote notification and before it is delivered to the user) then use the above delegate method to define an alternative solution.

Once the device received the remote notification and before displaying it to the user, the system will run this service extension. First, the system will call didReceiveNotificationRequest , here you can get the notification data from UNNotificationRequest , and get the media URL and start downloading it. The system will call serviceExtensionTimeWillExpire method to tell you that allotted time to download the content is going to get over. Here is the place where you can have some alternative solutions, maybe you can replace it with a static image, video or audio.

Notification Content

Go to file->New->Target , select Notification Content

This content extension helps developers to add their own view or custom views and also for handling the user actions on the notification. But these views are non-interactive.

Once you add the target, NotificationViewController.h, NotificationViewController.m, MainInterface.storyboard and info.plist files will be created.

Please use MainInterface.storyboard to customize the notification view. Select Notification View Controller Scene, and tap on Main View and go to Size inspector and set the height same as its width.

NotificationViewController  Class extends UNNotificationContentExtension with main two delegate methods didReceiveNotification and didReceiveNotificationResponse

The system calls didReceiveNotificationResponse delegate method in this extension when the user taps on any action buttons.

Let us see how to create a notification with action buttons and media file

Attaching image to notification

Using UNMutableNotificationContent class, developers can add rich content to the notification.

In the case of a local notification, we can add the path of images, audio or video to the UNMutableNotificationContent.attachments.

    // Creating notification Content object and attaching image file

    UNMutableNotificationContent *notificationcontent = [[UNMutableNotificationContent alloc] init];

    notificationcontent.title = [NSString localizedUserNotificationStringForKey:@"New Arrivals" arguments:nil];

    notificationcontent.body = [NSString localizedUserNotificationStringForKey:@"New arrival of Your favourite products!"

                                                         arguments:nil];

    notificationcontent.sound = [UNNotificationSound defaultSound];

    notificationcontent.categoryIdentifier=@"com.mcoe.notificationcategory.timerbased";

    NSError *error=nil;

    // reading image from bundle and copying it to document directory.

    NSURL *fileFromBundle =[[NSBundle mainBundle] URLForResource:@"psc" withExtension:@"png"];

    // Destination URL

    NSURL *url = [[self applicationDocumentsDirectory]URLByAppendingPathComponent:@"psc.png"];

    NSError *error1;

    // copying from bundle to document directory

     [[NSFileManager defaultManager]copyItemAtURL:fileFromBundle toURL:url error:&error1];

    // Creating attachment with image url

    UNNotificationAttachment *image_attachment=[UNNotificationAttachment attachmentWithIdentifier:@"com.mcoe.notificationcategory.timerbased" URL:url options:nil error:&error];

    notificationcontent.attachments=[NSArray arrayWithObject:image_attachment];

    notificationcontent.badge = @([[UIApplication sharedApplication] applicationIconBadgeNumber] + 1);

Adding Actions to Notification

There are mainly 3 kinds of actions

  • Default Actions – The default action is when the user opens the App from notification.
  • Custom Actions – Quick action can be executed directly from the notification itself without launching the App. These Custom actions can be background or foreground. Background custom actions can dismiss the notification and the System will be providing a limited amount of time in the background to execute the custom action. The foreground actions can dismiss the notification and can launch the app to execute the     custom action.
  • Dismiss Actions

 

// creating 3 Notification Action, setting unique identifier and adding it to notification center
  UNNotificationAction *checkoutAction = [UNNotificationAction actionWithIdentifier:@"com.mcoe.notificationcategory.timerbased.yes"                                                                              title:@"Check out"                                                                         options:UNNotificationActionOptionForeground];

  UNNotificationAction *declineAction = [UNNotificationAction actionWithIdentifier:@"com.mcoe.notificationcategory.timerbased.no"                                                                               title:@"Decline"                                                                             options:UNNotificationActionOptionDestructive];

  UNNotificationAction *laterAction = [UNNotificationAction actionWithIdentifier:@"com.mcoe.notificationcategory.timerbased.dismiss"                                                                              title:@"Later"                                                                            options:UNNotificationActionOptionDestructive];

  NSArray *notificationActions = @[ checkoutAction, declineAction, laterAction ];

  UNNotificationCategory *notificationCategory=[UNNotificationCategory categoryWithIdentifier:@"com.mcoe.notificationcategory.timerbased" actions:notificationActions intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];    

  NSSet *categories = [NSSet setWithObject:notificationCategory]; 

  [_notiCenter setNotificationCategories:categories];

Scheduling the notification

Local notification can be triggered in 3 ways

  • Time interval

  • Calendar time

  • Location

 

Time Interval

UNTimeIntervalNotificationTrigger *trigger = [UNTimeIntervalNotificationTrigger
                                                  triggerWithTimeInterval:3.f repeats:NO];


  

Location

//Creating region object and generating Notification trigger object out of it.

CLLocationCoordinate2D officeArea = CLLocationCoordinate2DMake(12.970540,80.251060);
CLCircularRegion* officeRegion = [[CLCircularRegion alloc] initWithCenter:officeArea 
                                                                     radius:10 identifier:@"My Office Bay"];

        officeRegion.notifyOnEntry = YES;
        officeRegion.notifyOnExit = YES;     
        UNLocationNotificationTrigger* locationTrigger = [UNLocationNotificationTrigger
                                                  triggerWithRegion:officeRegion repeats:YES];

Creating the request object and add it to the Notification Center

UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"com.mcoe.notificationcategory.timerbased"

                                                                          content:notificationcontent trigger:timerbasedtrigger];

    [_notiCenter addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {

        if (!error) {

            NSLog(@"added timer based NotificationRequest suceessfully!");
        }
    }];

Please note that the category identifier you assign to UNNotificationCategory object and the identifier name of  UNNotificationExtensionCategory in info.plist of notification content extension should be same.

As we can add multiple content extensions to the project, the system uses the category identifier name from the received notification and contact its corresponding extension codebase to call its delegate methods.

UNNotificationExtensionInitialContentSizeRatio in info.plist of notification content extension Indicates the aspect ratio of custom interface. Its value is between 0 and 1.

1 indicates that the custom interface height is equal to its width.

0 indicates that its height will be half of its total width.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)