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:

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

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 SDK to integrate them with our platform. The SDK supports animated and non-animated notifications with carousel themes.

To use these extensions:

  • Your app should run on iOS 10 or later
  • You use the latest version of Xcode
  • Your app's notification payload must contain the mutable-content flag set as '1' to invoke the notification service extension

Set up notification service extension

This notification service extension is responsible to modify the rich media content of the notification before it is presented to a user and send the push notification delivered tracking details to Blueshift.
Perform the following steps to add a notification service extension target in your app, and then use the Blueshift 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:

  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 notification service extension info.plist file.
  3. After you configure the extension, add the following lines in the Podfile to create 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 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.

  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 method 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.
iOS SDK v2.1.7 onwards, the SDK uses appGroupId to improve the push notification delivery tracking. Now, call the following method 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
        BlueShiftPushNotification.sharedInstance()?.apiKey = "YOUR API KEY"
        //Check if the notification is from Blueshift
        if BlueShiftPushNotification.sharedInstance()?.isBlueShiftPushNotification(request) == true, let attachments = BlueShiftPushNotification.sharedInstance()?.integratePushNotificationWithMediaAttachements(for: request, andAppGroupID: "YOUR APP GROUPID") as? [UNNotificationAttachment] {
            bestAttemptContent?.attachments = attachments
        } else {
            //handle notifications if not from Blueshift
        }
        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];
    [[BlueShiftPushNotification sharedInstance] setApiKey:@"YOUR API KEY"];
    
    // Modify the notification content here...
    if([[BlueShiftPushNotification sharedInstance] isBlueShiftPushNotification:request]) {
        self.bestAttemptContent.attachments = [[BlueShiftPushNotification sharedInstance] integratePushNotificationWithMediaAttachementsForRequest:request andAppGroupID:@"YOUR APP GROUPID"];
    } else {
        //handle notifications if not from Blueshift
    }
    
   self.contentHandler(self.bestAttemptContent);
}

- (void)serviceExtensionTimeWillExpire {
    
    // Called just before the extension will be terminated by the system.
    // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
    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.
Perform the following steps to add a notification content extension target in your app, and then use the Blueshift 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:

  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.

  2. 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
    • 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. 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.

  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.
    Import our headers into the NotificationViewController.h file 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. Set appGroupID which will help to share the correct deep-link URL to 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

Set up the app group if you want to set up deep-links for each image in the carousel of a push notification:

  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 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.

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, inside the Notification service extension, and in the Notification content extension.

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.

let blueShiftPushDelegatge = BlueshiftPushNotificationEvents()
config.blueShiftPushDelegate = blueShiftPushDelegatge
BlueshiftPushNotificationEvents* blueShiftPushDelegatge = [BlueshiftPushNotificationEvents alloc]init];
config.blueShiftPushDelegate = blueShiftPushDelegatge

Implement below method to get the push notification click callback. This callback method will be called when a user clicks on the push notification and it will deliver the push notification payload.
func pushNotificationDidClick(_ payload: [AnyHashable : Any]?)

Broadcast user response for push permission dialog

From SDK v2.2.0 onwards, the SDK will broadcast a notification on responding to push permission dialog.
As the handles the registering for the remote notification, 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:

Did this page help you?