SDK

Remote Notifications

In this page you'll learn how notifications are handled in your app and what all the options at your disposal to create a great messaging experience for your users.

Notificare supports several types of interactive and actionable notifications that will be handled for you without any extra development. If you are going to prevent this default behaviour, please note that you will have to either handle all the functionality yourself (metrics logging, presenting UI or collect replies) or if you don't, you understand that some features will not work as advertised.

Receiving Notifications

In Notificare we will streamline how notifications are handled for iOS 9 and higher. This is automatically handled for you and there's only two major interactions your app needs to account for, namely your app needs to react when notifications are received in foreground (while in use) and in background (when your app not being used). The first thing you need, to handle all types of notifications, is to make sure your app is declaring the following permissions in your app's Info.plist file:

ios privacy plist

This will make sure your app can request access to the device's camera, microphone or photo library whenever it is needed to reply to notifications with photos or videos.

If you are considering supporting non-HTTPS pages when using the Webpage notification type you will need to also declare a more permissive ATS policy as follows:

declare ats in plist

Then your App.js, you'll need to implement the following event listener in order to receive a notification whenever it arrives and the app is being used:

this.eventEmitter.addListener('remoteNotificationReceivedInForeground', (data) => {
     //Here you probably don't want to interrupt the user and simply show that a notification has arrive with an in-app badge
});

The best approach when the app is being used and a notification arrives, is to not interrupt the user, you can save this information and display some UI element that warns the user without interrupting whatever the user was doing.

But in most cases, notifications will arrive when the app is not being used. Users will click on it from the notification center or lock screen and you will want to show those immediately to the user. In those cases the following event will be triggered:

this.eventEmitter.addListener('remoteNotificationReceivedInBackground', (data) => {

});

Whenever this delegate is triggered you will need to handle it accordingly by presenting the notification. This is achieved by using the following method:

this.eventEmitter.addListener('remoteNotificationReceivedInBackground', (data) => {
    Notificare.presentNotification(data);
});

Our SDK also allows you to define which notification's authorization options you would like to request from your user. This is an optional step, if not defined we will register UNAuthorizationOptionAlert, UNAuthorizationOptionBadge and UNAuthorizationOptionSound by default. To define authorization options please add the following to your AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    if (@available(iOS 13.0, *)) {
        [NotificareReactNativeIOS setAuthorizationOptions:UNAuthorizationOptionAlert + UNAuthorizationOptionBadge + UNAuthorizationOptionSound + UNAuthorizationOptionProvidesAppNotificationSettings + UNAuthorizationOptionProvisional + UNAuthorizationOptionAnnouncement];
    } else {
        if (@available(iOS 12.0, *)) {
            [NotificareReactNativeIOS setAuthorizationOptions:UNAuthorizationOptionAlert + UNAuthorizationOptionBadge + UNAuthorizationOptionSound + UNAuthorizationOptionProvidesAppNotificationSettings + UNAuthorizationOptionProvisional];
        } else {
            if (@available(iOS 10.0, *)) {
                [NotificareReactNativeIOS setAuthorizationOptions:UNAuthorizationOptionAlert + UNAuthorizationOptionBadge + UNAuthorizationOptionSound];
            }
        }
    }

    [NotificareReactNativeIOS launch:launchOptions];


    ...more code

}

Please note the following authorization options are available: UNAuthorizationOptionAnnouncement. first introduced in iOS 13, the options UNAuthorizationOptionProvidesAppNotificationSettings and UNAuthorizationOptionProvisional are available since iOS 12 and UNAuthorizationOptionCarPlay is available since iOS 10. The option UNAuthorizationOptionAnnouncement will allow Siri to automatically read out messages over AirPods, the UNAuthorizationOptionProvisional option will register for notifications with provisional authorization, this means that users will not be prompted to with the permission dialog to accept notifications. Although this might be a great way to opt-in users to remote notifications, any message you sent afterwards will be deliver quietly. Messages delivered quietly will not be shown in the lock screen or play a sound.

Also note that if you implement the UNAuthorizationOptionProvidesAppNotificationSettings option, notifications from your app will display a button in both the Instant Tuning menu and Notification Settings. The purpose of that button is to provide users a shortcut to your app settings where they can fine-tune which kind of notifications they would like to receive. Implementing such settings views is highly recommended as it could be the reason between allowing your app to keep display notifications or being mute completely. If you do implement this option it is mandatory that you implement the following event listener:

this.eventEmitter.addListener('shouldOpenSettings', (data) => {
    // When triggered you should direct users to your own settings view
});

This will give you the opportunity to present your users with the in-app settings view where you should allow them to customize what kind of notifications they should receive. If the user clicked the button from a specific notification you will receive that object too. If it came from the Notification Settings that object will be nil.

Optionally since iOS 10, you can enable presentation options when your app is in the foreground. This will allow you to show a small banner on the top of your app, play a sound or badge your app, whenever a notification arrives and your app is being used. By default our library will set this to UNNotificationPresentationOptionNone, but you can change this behaviour to match your needs:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    if (@available(iOS 14.0, *)) {
        [NotificareReactNativeIOS setPresentationOptions:UNNotificationPresentationOptionBanner + UNNotificationPresentationOptionSound + UNNotificationPresentationOptionBadge];
    } else {
        if (@available(iOS 10.0, *)) {
            [NotificareReactNativeIOS setPresentationOptions:UNNotificationPresentationOptionAlert + UNNotificationPresentationOptionSound + UNNotificationPresentationOptionBadge];
        }
    }

    [NotificareReactNativeIOS launch:launchOptions];


    ...more code

}

Also since iOS 10, if you are using Rich Push Templates you can define category options. These options can define how your notifications and actions will behave. The options UNNotificationCategoryOptionCustomDismissAction, UNNotificationCategoryOptionAllowInCarPlay and UNNotificationCategoryOptionNone were introduced in iOS 10, the options UNNotificationCategoryOptionHiddenPreviewsShowTitle and UNNotificationCategoryOptionHiddenPreviewsShowSubtitle were introduced in iOS 11 and the option UNNotificationCategoryOptionAllowAnnouncement was first introduced in iOS 13. By default, in iOS 10 we will use UNNotificationCategoryOptionCustomDismissAction and in iOS 11 or higher UNNotificationCategoryOptionCustomDismissAction and UNNotificationCategoryOptionHiddenPreviewsShowTitle, but you can change this behaviour to match your needs:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    if (@available(iOS 10.0, *)) {
        [NotificareReactNativeIOS setCategoryOptions:UNNotificationCategoryOptionCustomDismissAction];
    }

    if (@available(iOS 11.0, *)) {
        [NotificareReactNativeIOS setCategoryOptions:UNNotificationCategoryOptionCustomDismissAction + UNNotificationCategoryOptionHiddenPreviewsShowTitle];
    }

    if (@available(iOS 13.0, *)) {
        [NotificareReactNativeIOS setCategoryOptions:UNNotificationCategoryOptionCustomDismissAction + UNNotificationCategoryOptionHiddenPreviewsShowTitle + UNNotificationCategoryOptionAllowAnnouncement];
    }

    [NotificareReactNativeIOS launch:launchOptions];

    ...more code

}

System Notifications

In Notificare you can send silent notifications that will wake up your app and can be used to download new data. These are called System Notifications and will not be added to the device's lock screen or notification center nor they will be added to the inbox (if implemented).

To be notified whenever those notifications are received, add the following event listeners to your App.js:

this.eventEmitter.addListener('systemNotificationReceivedInBackground', (data) => {
    // Handle silent notification when received in background
});

this.eventEmitter.addListener('systemNotificationReceivedInForeground', (data) => {
    // Handle silent notification when received in foreground
});

Notifications from Unknown Sources

In some apps it possible you're also using other providers to send remote notifications, when that is the case Notificare will recognize an unknown notification and trigger an event that you can use to further handle that notification. To be notified whenever that happens, add the following to your App.js:

this.eventEmitter.addListener('unknownNotificationReceived', (data) => {
    //Unknown notification received
});

this.eventEmitter.addListener('unknownNotificationReceivedInBackground', (data) => {
    //Unknown notification received while app was in background
});

this.eventEmitter.addListener('unknownNotificationReceivedInForeground', (data) => {
    //Unknown notification received while app was in foreground
});

It is also possible that notifications from unknown sources handle actions or text input from users, when that is the case the following event is triggered:

this.eventEmitter.addListener('unknownActionForNotificationReceived', (data) => {
    //Handle action from a different source
});

In modern apps, this is a great way of creating interactions between notifications and your own app content, allowing you to send messages that can eventually drive the user to open content hidden deeper in your app.

To prepare your app to handle deep links is not complicated and will allow you to handle not only Deep Link notification types, but also any link made from an web page. In order to indicate your app that you will handle a custom URL scheme you simply have to declare the following in your app's .plist file:

![]ios-url-schemes.png)

Because these deep links can also be called from links in HTML content or actions in your notifications, you must also declare any URL Scheme you considering to use in the Launch Services Queries Schemes in your app's .plist file as shown below:

ios launch services url schemes

Then in Xcode, in your AppDelegate.m file make sure your implement the following methods:

//For iOS 9
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
    [NotificareReactNativeIOS handleOpenURL:url withOptions:nil];
    return YES;
}

//Deep Link was executed when your app was inactive
- (void)notificarePushLib:(NotificarePushLib *)library didReceiveLaunchURL:(NSURL *)launchURL {
    [NotificareReactNativeIOS handleOpenURL:launchURL withOptions:nil];
}


//For iOS 10 and higher when app is in background, foreground or inactive
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    [NotificareReactNativeIOS handleOpenURL:url withOptions:options];
    return YES;
}

Then in your App.js you must implement the following event listener which will be triggered whenever deep links are executed:

this.eventEmitter.addListener('urlOpened', (data) => {
   //Handle URL
});

this.eventEmitter.addListener('launchUrlReceived', (data) => {
   //Handle URL when triggered when app was inactive
});

Another situation where you will also want to handle deep links is when users click in a link in a HTML or Web Page notification. If that link should open a view in your app you will want to intercept those clicks and handle it the same way you handle deep links.

First make sure you declare those URL Schemes in the Notificare.plist file as follows:

ios notificare plist url schemes

Our library will then intercept all the links using those URL Schemes and trigger the following event:

this.eventEmitter.addListener('urlClickedInNotification', (data) => {
   //Handle URL when clicked from a notification
});

Inbox

With our library it's extremely easy to implement an in-app inbox. Implementing an inbox increases considerably the engagement rates of your notifications simply because messages will always be available inside your app. To activate the inbox functionality, please follow the instructions described here.

After activating this functionality, implement the following event listener in your App.js which will be triggered whenever the inbox initializes or reloads its data:

this.eventEmitter.addListener('inboxLoaded', (data) => {
   //Update your list of inbox items
});

To retrieve the list of messages the user have previously received, invoke the following method:

Notificare.fetchInbox().then((inboxItems) => {
    //Handle the list of inbox items
}).catch((e) => {
    //Handle error
});

To open a message from the list of messages in the inbox, please use the following method:

//Use an object from the fetchInbox() result
let inboxItem = inboxItems[0];
Notificare.presentInboxItem(inboxItem);

At anytime you can also delete a notification from the inbox:

//Use an object from the fetchInbox() result
let inboxItem = inboxItems[0];
Notificare.removeFromInbox(inboxItem).then((result) => {
    //Handle success
}).catch((e) => {
    //Handle error
});

Additionally you can also mark a message as read by invoking the following method:

//Use an object from the fetchInbox() result
let inboxItem = inboxItems[0];
Notificare.markAsRead(inboxItem).then((result) => {
    //Handle success
}).catch((e) => {
    //Handle error
});

Additionally, in 2.4 and up, you can also mark all messages as read by invoking the following method:

Notificare.markAllAsRead().then((result) => {
    //Handle success
}).catch((e) => {
    //Handle error
});

Finally to remove all the items in the inbox you would do the following:

Notificare.clearInbox().then((result) => {
    //Handle success
}).catch((e) => {
    //Handle error
});

If you've configured your inbox functionality to use the AutoBadge feature, then you can implement the following event listener in your App.js. This will be triggered whenever there's changes to the inbox items unread count and can help you manage your UI:

this.eventEmitter.addListener('badgeUpdated', (badge) => {
   //Update in-app badge
});

Notification Delegates

Optionally, you can implement listeners which can inform your app when certain operations are done or failed, so you can show more UX/UI elements, perform other operations, etc. In your component you can add the following listeners:

this.eventEmitter.addListener('notificationWillOpen', (data) => {

});

this.eventEmitter.addListener('notificationOpened', (data) => {

});

this.eventEmitter.addListener('urlClickedInNotification', (data) => {

});

this.eventEmitter.addListener('notificationClosed', (data) => {

});

this.eventEmitter.addListener('notificationFailedToOpen', (data) => {

});

Action Delegates

The same can be achieved for actions. In your component you can add the following listeners:

this.eventEmitter.addListener('actionWillExecute', (data) => {

});

this.eventEmitter.addListener('actionExecuted', (data) => {

});

this.eventEmitter.addListener('shouldPerformSelectorWithUrl', (data) => {

});

this.eventEmitter.addListener('actionNotExecuted', (data) => {

});

this.eventEmitter.addListener('actionFailedToExecute', (data) => {

});

Notification Service Extension

In iOS 10, Apple introduced a new extension that enables your apps to process notifications before they are displayed to the users. This can be used to provide users with rich content in the lock screen or simply change the content of your messages in the client side of things. To add a Notification Service Extension to your React Native app please follow the instructions from our native library located here.