Push rich notifications to customers

This article provides steps on how you can use Blueshift's SDK to integrate notifications from your app with our platform to send rich notifications to your iOS app's users.

📘

Wait. Are you ready for this part?

In this article, we'll show you how you can use the SDK to integrate notifications from your app with Blueshift. However, you cannot proceed until you already have the SDK in your project and you can use it in your app. In addition, you have to generate a .pem file and upload it to our platform so that we can send notifications to your users. If not, then we suggest that you do those things first and then come back here to integrate your app's notifications with us.

It's absolutely not complicated. We promise. And, like earlier, we'll wait. No pressure. :relaxed:

Blueshift iOS Extension SDK supports the below push notification types.

  • Rich media(image, GIF, video) push notification.
  • Custom action button push notification (supported from extension SDK v2.2.2).
  • Auto update badge count based on number of pending push notifications (supported from core & extension SDK v2.4.1). Check more here.
  • Carousel image push notification.

To handle media-based custom push notifications, Apple provides two notification extensions:

  • Notification service extension
    SDK uses this extension to,
    • Download and modify the media content of the rich media push and carousel push notification before it is presented to the user.
    • Set up the custom action buttons for push notification before it is presented to a user.
    • To auto update the badge count based on pending push notifications.
  • Notification content extension
    SDK uses this extension to design and display the animated and non-animated carousel notifications.

If you plan to use Blueshift's rich push studio to create and send rich notifications to your users, you have to add these targets and use the Blueshift iOS extension SDK to integrate them with our platform.

To use these extensions in your project:

  • Your app should run on iOS 10 or later
  • You use the latest version of Xcode

If you only want to use the Rich media, custom action button and auto update push notifications, then you can integrate only the Notification service extension.

If you want to use Rich media, custom action button, auto update badge and Carousel push notifications, then integrate both Notification service and content extensions.

📘

Important

In order to make our ‘delivered’ metric at par with the industry standard, we have updated how we compute the ‘delivered’ metric for push messages. Instead of relying on an acknowledgment from the SDK (i.e. the user’s phone), we are now inferring a ‘delivered’ event from APNS or FCM for a specific ‘send’. Check our product updates for more details.


Set up notification service extension

This notification service extension is responsible to download and modify the rich media content of the notification before it is presented to a user. Also, SDK uses this extension to auto update badge and set up the custom action buttons for the push notification.

Perform the following steps to add a notification service extension target in your app, and then use the Blueshift Extension SDK to integrate our platform with it:

  1. On your Mac, launch Xcode and open your app's project.
  2. On Xcode menu bar, click File > New > Target.
  3. On the Choose a template for your new target dialog that appears, click Notification Service Extension.
  4. On the Choose options for your new target dialog, provide the details and then click Finish. Click Activate on the Activate Scheme dialog. You should see a new folder created under your project with the name that you specify.
  5. Select the extension's target under your project, specify a bundle identifier and a provisioning profile for it, and fill in the General details.

👍

:bulb: Where are the targets? :owlbert-thinking:
If you are wondering where can you find the targets in your Xcode project, then here they are:

2172
  1. Expand the NotificationService folder in the left panel, under project navigator in Xcode. If the programming language is Objective-C, you can see the NotificationService.h, NotificationService.m, and Info.plist files.
    If the programming language is Swift, you can see the NotificationService.swift and Info.plist files.
  2. If you want to support HTTP-based URLs for images, add application transport security into the notification service extension info.plist file.
  3. Add Blueshift iOS Extension SDK to the project.
    Using CocoaPods
    After you configure the extension, add the following lines in the Podfile to create dependency for the notification service extension target.
target 'APP EXTENSION TARGET NAME' do
        pod 'BlueShift-iOS-Extension-SDK'
end

For example, if the name of the notification service extension target is NotificationService, add the following lines:

target 'NotificationService' do
    pod 'BlueShift-iOS-Extension-SDK'
end

👍

:bulb: Wait, what? Podfile? What Podfile? :owlbert-thinking:
So if you look at the setup article, you'll see that we added a dependency on our SDK in your app, and we defined that dependency in the Podfile. We created the Podfile in the directory where your Xcode project resides. To access your Podfile, launch the Terminal app on your Mac and change directory to the location where your Xcode project resides, and open it using Xcode.

But, really, we recommend that you go through the setup article. That article provides a lot of information you need on the Podfile.

Using Swift Package Manager
Refer to this document to add Blueshift iOS Extension SDK to your notification service extension target.

Using Carthage
Refer to this document to add Blueshift iOS Extension SDK to your notification service extension target.

  1. Now that you have specified dependencies, include the header files from our SDK into the NotificationService files.

Import the header into NotificationService.h if the programming language is Objective-C:

#import <BlueShift-iOS-Extension-SDK/BlueShiftAppExtension.h>

And call the following method in NotificationService.m to download and show the attachment in a push notification.

If the programming language is Swift, and you are not using use_frameworks! in the podfile, then you need to create a bridge-header file for the notification service extension and then import our BlueShiftAppExtension.h Objective C header in it. If you have use_frameworks! in the podfile, then import BlueShift_iOS_Extension_SDK.

Setting API key and AppGroupId in the service extension is not required anymore. Now, write the following to download and show the attachment in a push notification:

import UserNotifications
import BlueShift_iOS_Extension_SDK

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        //Check if push notification is from Blueshift
        if BlueShiftPushNotification.sharedInstance()?.isBlueShiftPushNotification(request) == true {
            //Feature supported from SDK v2.4.1
            //Get updated the badge count and set it to bestAttemptContent
            if let updatedBadgeCount = BlueShiftPushNotification.sharedInstance()?.getUpdatedBadgeNumber(for: request) {
                bestAttemptContent?.badge = updatedBadgeCount;
            }
            
            //Download the rich media assets and set them as attachments to bestAttemptContent
            if let attachments = BlueShiftPushNotification.sharedInstance()?.integratePushNotificationWithMediaAttachements(for: request, andAppGroupID: nil) as? [UNNotificationAttachment] {
                bestAttemptContent?.attachments = attachments
            }
        } else {
            //handle notifications if not from Blueshift
        }
        // Define the custom actions.
        if let bestAttemptContent = bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }
    
    override func serviceExtensionTimeWillExpire() {
        if let attachments = BlueShiftPushNotification.sharedInstance()?.attachments {
            bestAttemptContent?.attachments = attachments
        } else {
            //handle notifications if not from Blueshift
        }
        if let bestAttemptContent = bestAttemptContent, let contentHandler = contentHandler {
            contentHandler(bestAttemptContent)
        }
    }
}

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];
    
    //Check if the notification is from Blueshift
    if([[BlueShiftPushNotification sharedInstance] isBlueShiftPushNotification:request]) {
        //Update the badge count based on pending notifications
        NSNumber* updatedBadgeCount = [[BlueShiftPushNotification sharedInstance] getUpdatedBadgeNumberForRequest:request];
        if (updatedBadgeCount) {
            self.bestAttemptContent.badge = updatedBadgeCount;
        }
        
        //Download media and assign as attachments
        self.bestAttemptContent.attachments = [[BlueShiftPushNotification sharedInstance] integratePushNotificationWithMediaAttachementsForRequest:request andAppGroupID:nil];
    } else {
        //handle notifications if not from Blueshift
    }
    
   self.contentHandler(self.bestAttemptContent);
}

- (void)serviceExtensionTimeWillExpire {
    
    // Called just before the extension will be terminated by the system.
    if([[BlueShiftPushNotification sharedInstance] hasBlueShiftAttachments]) {
        self.bestAttemptContent.attachments = [BlueShiftPushNotification sharedInstance].attachments;
    }
    self.contentHandler(self.bestAttemptContent);
}

Set up notification content extension

This notification content extension is responsible for designing and showing the animated and non-animated carousel push notifications.

Make sure you set up the app group id in your project and set it during SDK initialization in your main app target and in the notification content extension. App group id helps the SDK to track the push deep link accurately for the carousel push notifications.
Refer to this section to know more on App group id.

Perform the following steps to add a notification content extension target in your app, and then use the Blueshift Extension SDK to integrate our platform with it:

  1. On your Mac, launch Xcode and open your app's project.
  2. On Xcode menu bar, click File > New > Target.
  3. On the Choose a template for your new target dialog that appears, click Notification Content Extension.
  4. On the Choose options for your new target dialog, provide the details and then click Finish. Click Activate on the Activate Scheme dialog. You should see a new folder created under your project with the name that you specify.
  5. Select the extension's target under your project, specify a bundle identifier and a provisioning profile for it, and fill in the General details.

👍

:bulb: Where are the targets? :owlbert-thinking:
If you are wondering where can you find the targets in your Xcode project, then here they are:

2172
  1. Expand the NotificationContent folder in the left panel, under project navigator in Xcode. If the programming language is Objective-C, you can see the NotificationViewController.h, NotificationViewController.m, MainInterface.storyboard, and Info.plist files.

If the programming language is Swift, you can see the NotificationViewController.swift, MainInterface.storyboard, and Info.plist files.

  1. Add carousel_animation and carousel categories in the info.plist. Select Info.plist, secondary click (or right click) on it > Open As > Source Code and add the following:
    • NSExtensionAttributes inside NSExtension
    • UNNotificationExtensionCategory with array items carousel_animation and carousel
    • UNNotificationExtensionDefaultContentHidden with value false
    • UNNotificationExtensionInitialContentSizeRatio with value 1.
      For example:
<key>NSExtension</key>
<dict>
    <key>NSExtensionAttributes</key>
    <dict>
        <key>UNNotificationExtensionCategory</key>
        <array>
            <string>carousel_animation</string>
            <string>carousel</string>
        </array>
        <key>UNNotificationExtensionDefaultContentHidden</key>
        <false/>
        <key>UNNotificationExtensionInitialContentSizeRatio</key>
        <real>1</real>
    </dict>
    <key>NSExtensionMainStoryboard</key>
    <string>MainInterface</string>
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.usernotifications.content-extension</string>
</dict>
  1. Add Blueshift iOS Extension SDK to the project.
    Using CocoaPods
    After you configure the extension, add the following lines in the Podfile to specify dependency for the notification content extension target as well.
target 'APP EXTENSION TARGET NAME' do
        pod 'BlueShift-iOS-Extension-SDK'
end

For example, if the name of the notification content extension target is NotificationContent, add the following lines:

target 'NotificationContent' do
        pod 'BlueShift-iOS-Extension-SDK'
end

👍

:bulb: Wait, what? Podfile? What Podfile? :owlbert-thinking:
So if you look at the setup article, you'll see that we added a dependency on our SDK in your app, and we defined that dependency in the Podfile. We created the Podfile in the directory where your Xcode project resides. To access your Podfile, launch the Terminal app on your Mac and change directory to the location where your Xcode project resides, and open it using Xcode.

But, really, we recommend that you go through the setup article. That article provides a lot of information you need on the Podfile.

Using Swift Package Manager
Refer to this document to add Blueshift iOS Extension SDK to your notification content extension target.

Using Carthage
Refer to this document to add Blueshift iOS Extension SDK to your notification content extension target.

  1. Now that you have specified dependencies, open the MainInterface.storyboard file and delete the Label from the NotificationViewController view. Also, delete label IBOutlet from the NotificationViewController class.

  2. Include the headers from our SDK into the NotificationViewController and inherit class BlueShiftCarousalViewController.

Import our headers into the NotificationViewController.h file as below if the programming language is Objective-C:

#import <BlueShift-iOS-Extension-SDK/BlueShiftAppExtension.h>
  
@interface NotificationViewController : BlueShiftCarousalViewController

@end

If the programming language is Swift, then import BlueShift_iOS_Extension_SDK in it.
Now, set appGroupID which will help to share the correct deep-link URL to the host app and send click details to Blueshift.

The NotificationViewController.swift and NotificationViewController.m should look like:

import BlueShift_iOS_Extension_SDK

class NotificationViewController: BlueShiftCarousalViewController, UNNotificationContentExtension {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        appGroupID = "YOUR APP GROUP ID"
    }
    
    func didReceive(_ notification: UNNotification) {
       //Check if notification is from Blueshift
        if isBlueShiftCarouselPush(notification) {
            showCarousel(forNotfication: notification)
        } else {
            //handle notifications if not from Blueshift
        }
    }

    func didReceive(_ response: UNNotificationResponse, completionHandler completion: @escaping (UNNotificationContentExtensionResponseOption) -> Void) {
        //Check if the action is from Blueshift carousel
        if isBlueShiftCarouselActions(response) {
            setCarouselActionsFor(response) { (option) in
                completion(option)
            }
        } else {
            //handle action if not from Blueshift
        }
    }
}
@implementation NotificationViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.appGroupID = @"YOUR APP GROUP ID";
}

- (void)didReceiveNotification:(UNNotification *)notification {
    if([self isBlueShiftCarouselPushNotification:notification]) {
        [self showCarouselForNotfication:notification];
    } else {    
         //handle notifications if not from Blueshift
    }
}

- (void)didReceiveNotificationResponse:(UNNotificationResponse *)response completionHandler:(void (^)(UNNotificationContentExtensionResponseOption))completion {
    //Place following codes after your code lines
    if([self isBlueShiftCarouselActions:response]) {
        [self setCarouselActionsForResponse:response completionHandler:^(UNNotificationContentExtensionResponseOption option) {
            completion(option);
        }];
    } else {
        //handle action if not from Blueshift
    }
}

@end

Add an app group

App Group allows the sharing of data between the main application target and other application targets such as notification content extension. Blueshift Extension SDK uses App groups to share the carousel push notification click data with the main application target. It helps to track the push notification click correctly and deliver the deep-link to the main application.

Set up the app group:

  1. To add an app group, launch and sign in to the Apple Developer Portal in a browser.
  2. Click Certificates, Identifiers & Profiles.
  3. Under Identifiers, select App Groups and click the + button to add a new group.
  4. Provide a description and a new group ID, and click Continue.
  5. Click the Register button and then click Done.
  6. Under Identifiers, select App IDs.
  7. Select your app's ID from the list that appears and click the Edit button.
  8. Under App Services, enable App Groups and then click Done.
  9. Under Identifiers, select App IDs.
  10. Select your application's ID from the list that appears and click the Edit button.
  11. Under the App Groups service, click Edit.
  12. In the App Group Assignment section, select the app group that you created and click Continue.
  13. In the next section, click Assign and then click Done.

After you do this for your main app target, repeat steps 7-13 of the above procedure for the notification service and content extensions in your app.

  • Specify the app group ID under Signing & Capabilities of your app's project
    1. In Xcode, select your app's target and then click Signing & Capabilities.
    2. Under Signing & Capabilities, enable App Groups and provide the ID of the app group that you created above.
1678

Perform the steps of this procedure for the notification service and content extension targets as well.

Make sure you set the app group id during the SDK initialization in the main app and in the Notification content extension.


Custom Action button push notifications

From iOS SDK v2.2.2, you can configure the push notification with custom action buttons using Blueshift Push studio. You can create custom button labels using Push studio based on your use case and add a deep link to the button, Blueshift extension SDK will take care of rendering it on the device. The custom button deep link will work the same as the regular push notification deep link. When a user clicks on the push notification button, the associated deep link will be delivered in the application open URL: options: method of the AppDelegate class. You can add your business logic to handle the deep link from there. Refer to this document to know more about creating the custom action push notifications using Blueshift Push studio.

Auto update badge count

Blueshift's core iOS SDK (v2.4.1 & above) and the extension SDK (v2.4.1 & above) collaboratively take care of auto updating the badge count. In order to use this feature, you will have to update the notification extension code as mentioned in sample code snippet of this section.

SDK auto updates the badge count for the application when

  • A new auto-update badge count type of push notification is received.
  • A single push notification of auto-update badge count type is dismissed or clicked.

SDK does not handle the case when a group of push notifications is cleared by user. The iOS does not give any callback for this case. In order to handle this case, SDK exposes a helper method which auto updates the badge count based on pending notifications. You can call this method on any lifecycle method such as, applicationWillEnterForeground. So whenever the app goes to background, the badge count will be updated to match the pending notifications.

BlueShift.sharedInstance()?.refreshApplicationBadge(completionHandler: { 
  });
[[BlueShift sharedInstance] refreshApplicationBadgeWithCompletionHandler:^{
    }];

Push notifications callbacks

Our SDK provides callbacks for the push notification click event. Create a class that inherits from BlueShiftPushDelegate. For example, we create BlueshiftPushNotificationEvents class to receive the callback for push notification click. You will need to set the delegate object during the SDK initialization. Refer to this sample app class to implement the delegate methods.

let blueShiftPushDelegatge = BlueshiftPushNotificationEvents()
config.blueShiftPushDelegate = blueShiftPushDelegatge
BlueshiftPushNotificationEvents* blueShiftPushDelegatge = [BlueshiftPushNotificationEvents alloc]init];
config.blueShiftPushDelegate = blueShiftPushDelegatge
  • When a user taps on the push notification banner
    Implement pushNotificationDidClick(_ payload: [AnyHashable : Any]?) to get callback when a user clicks on the push notification banner.

  • When a user taps on the action button of the custom action button push notification
    Implement pushNotificationDidClick(_ payload: [AnyHashable : Any]?, forActionIdentifier identifier: String?) method to get callback when a user clicks on the push notification action button.

  • When a user taps on the carousel push notification's image
    Implement handleCarouselPush(forCategory categoryName: String, clickedWith index: Int, withDetails details: [AnyHashable : Any]) method to get callbacks when user clicks on animated or non-animated carousel push notification.

Broadcast user response for push permission dialog

From SDK v2.2.0 onwards, the SDK will broadcast a notification on responding to the push permission dialog.

As the SDK handles the remote notification registration, it will broadcast a notification to notify the response of the user to the push permission dialog. To get the authorization status, ensure that you set up an observer for the BlueshiftPushAuthorizationStatusDidChangeNotification notification.

The userInfo object of notification will have the authorization value under key status as 0 or 1.

NotificationCenter.default.addObserver(forName: Notification.Name(rawValue: "BlueshiftPushAuthorizationStatusDidChangeNotification"), object: nil, queue: OperationQueue.current) { notification in
     print("Push permission status : \(String(describing: notification.userInfo?["status"]))")
}
[[NSNotificationCenter defaultCenter] addObserverForName:@"BlueshiftPushAuthorizationStatusDidChangeNotification" object:nil queue:NSOperationQueue.currentQueue usingBlock:^(NSNotification * _Nonnull notification) {
    NSLog(@"Push permission status : %@", notification.userInfo[@"status"]);
}];

Create notifications in the rich push studio

Now, you can create notifications in the rich push studio of our platform and send notifications to your app's users. Ensure that you follow the guidelines for the images that you want add in your notifications.
You can use our Test the SDK integration document to troubleshoot the SDK integration issues.


What’s Next

At this point, you are quite familiar with our SDK and its features. In addition to tracking events on your app and sending push notifications, you can send in-app messages and fetch live-content from our platform to your app. For more information on how to do that, see: