Cheetah CES Docs Portal

Navigation
Home
GitHub
Email
Corporate Site


Notifications Kit

« Back to iOS Kit References

This kit supports the following:

  • Device registration for Push Notifications
  • Loyalty Platform message tracking
  • Rich Push Notification using Notification Service Extension
  • Local Notification Scheduling using UNUserNotificationCenter extension
  • Handling of Push Notification user responses
  • Setting of application’s badge count

Configuration

This documentation assumes that necessary setup like setting capabilities, providing usage texts in Info.plist is already done.

Creating Notification Service Extension for Rich Push Notifications

Supporting Rich Push Notifications requires creating a NotificationServiceExtension. Creating one can be done in XCode.

  1. In your project/workspace, go to File -> New -> Target
  2. Under the iOS tab, look for Notification Service Extension and select it
  3. Set its name to “NotificationService”
  4. Set your application as the executable target

Enabling Rich Push Notifications for Store Versions

The steps below assume that you already have an App ID setup for your application.

  1. Create a new App Group Identifier
    • Set the description to “YourAppName Group”
    • Set the Identifier to “group.your.app.bundle.id”
  2. Create an App ID for your Notification Service Extension
    • Set the name to “YourAppName NotificationServiceExtension”
    • Set the Bundle ID to “your.app.bundle.id.NotificationServiceExtension”
    • Enable App Groups capability and use the created group on step 1
  3. In your application’s App ID, enable App Groups and Push Notifications capabilities and use the created App Group on step 1
  4. Create App Store Distribution Provisioning Profile for your Notification Service Extension and select the same distribution certificate you used for your application’s provisioning profile

Localization

Add the following strings in your application’s Localizable.strings.

"RichPush.AddComment"
"RichPush.AddToMyEvents"
"RichPush.CertificateCodeCopiedToClipboard"
"RichPush.Clip"
"RichPush.Enter"
"RichPush.Like"
"RichPush.Respond"
"RichPush.TapToReadMore"

Usage

This section will use the default classes provided within the kit to simulate a straightforward integration with minimal modifications. Please note that even using the default classes, you still need to subclass them to provide implementations that don’t have default ones. To know which methods have defaults, please refer to Defaults section.

Setup

  1. Import frameworks to use its components

     import CheetahDigitalCore
     import CheetahDigitalNotifications
    
  2. Create a subclass of DefaultPushHandler and DefaultRichPushHandler classes preferably on each of their own files

     class AppPushHandler: DefaultPushHandler {
         // TODO: Override methods that don’t have default implementations
     }
    	
     class AppRichPushHandler: DefaultRichPushHandler {
         // TODO: Override methods that don’t have default implementations
     }
    
  3. Create a property that will hold an instance of DefaultNotificationHelper in your AppDelegate passing your classes on step 2

     let notificationHelper = DefaultNotificationHelper(pushHandler: AppPushHandler(), richPushHandler: AppRichPushHandler())
    
  4. Register for remote notifications and set UNUserNotificationCenterDelegate in your AppDelegate’s didFinishLaunchingWithOptions

     UNUserNotificationCenter.current().delegate = self
    
     notificationHelper.requestAuthorization(completion: { [weak self] (granted, _) in
         guard granted else { return }
            
         UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { settings in
             if settings.alertSetting == .enabled ||
                 settings.badgeSetting == .enabled ||
                 settings.soundSetting == .enabled {
                 DispatchQueue.main.async {
                     self?.notificationHelper.registerForRemoteNotifications()
                 }
             }
         })
     })
    
  5. Send device token to server in didRegisterForRemoteNotificationsWithDeviceToken method of your UNUserNotificationCenterDelegate

     notificationHelper.sendDeviceTokenToServerIfNeeded(deviceToken)
    
  6. Handle notification responses in didReceiveResponse method of your UNUserNotificationCenterDelegate when your application is not active

     notificationHelper.handleNotificationResponse(response, completionHandler: completionHandler)
    
  7. Display incoming notification in willPresentNotification method of your UNUserNotificationCenterDelegate when your application is in foreground

     completionHandler(.alert)
    
  8. Make your NotificationService class that was created here a subclass of the kit’s RichPushService and remove everything in it

     class NotificationService: RichPushService {}
    

Running Notification Service Extension

Make sure that the extension has an executable target set on its scheme. This should already be done during the creation of the extension.

  • Run the extension’s scheme
  • The executable target should run automatically
  • The service will start once a Rich Push Notification is received

Accessing Extra JSON if Rich Push Notifications

A field named extra_json could be added in the notification’s payload, it serves as a container for custom data that is not initially supported. As long as you have access on the notification’s payload, you have access to the extra_json.


Components

Constants

NotificationType

Enumeration of supported notification target. This represents what entity within the Loyalty Platform the notification is targeting.

  • award
  • challenge
  • clientEvents
  • contentPage
  • event
  • member
  • offer
  • offerResponse
  • post
  • reward

RichPushCategory

Enumeration of supported Rich Push Notification categories. This is used as an identifier for UNNotificationCategory.

  • challenge
  • contentPage
  • eventFavorite
  • offerCertificate
  • offerClip
  • offerCoupon
  • offerLink
  • postLike
  • postLikeComment

RichPushAction

Enumeration of supported Rich Push Notification quick actions. This is used as an identifier for UNNotificationAction.

  • clipOffer
  • commentPost
  • favoriteEvent
  • openCertificate
  • openChallenge
  • openContentPage
  • openCoupon
  • openOfferLink
  • likePost

For additional information regarding Rich Push Notification categories and actions, please refer to this document.

NotificationHelper

A protocol that contains properties and methods for managing notification-related functionalities.

pushHandler

An object conforming to PushHandler.

richPushHandler

An object conforming to RichPushHandler.

handleNotificationResponse

Method for handling incoming push notification responses.

requestAuthorization

Method for requesting authorization to allow the application to modify and/or interact with notifications.

registerForRemoteNotifications

Method for registering the device on Apple’s push notification service.

trackMessage

Method for tracking the received notification within the Loyalty Platform.

setApplicationBadgeCount

Method for changing the application’s badge count in the device’s home screen.

PushHandler

A protocol that contains methods for handling non-rich Push Notification responses.

handlePush

Method for handling incoming non-rich Push Notification responses.

handleObjectWithId

Method for handling notification with a target NotificationType.

handleNotificationWithoutType

Method for handling notifications without NotificationType.

handleContentPageWithName

Method for handling a content page with a given name.

handleClientEvents

Method for handling Client Events related to geofencing.

RichPushHandler

A protocol that contains methods for handling Rich Push Notification responses.

handleRichPushResponse

Method for handling incoming Rich Push Notification responses.

showMessage

Method for showing a message from the kit to the application.

showChallengeResponder

Method for displaying a Challenge Responder view.

showOfferResponseDetail

Method for displaying an Offer Response Detail view

Other methods for handling RichPushAction(s)

  • handleClipOffer
  • handleCommentPost
  • handleFavoriteEvent
  • handleOpenCertificate
  • handleOpenChallenge
  • handleOpenContentPage
  • handleOpenCoupon
  • handleOpenOfferLink
  • handleLikePost

RichPushService

A subclass of UNNotificationServiceExtension that has default implementations for setting up the Loyalty Platform’s supported Rich Push Notification features such as displaying an image, having quick actions, and having an extra JSON.

It modifies the incoming notification for it to display necessary views (image/buttons) depending on its payload. It only executes if the system (iOS) detects that the notification’s “mutable-content” payload is set to 1.

contentHandler

Completion block that should always be called regardless if the modification succeeded or failed. This is set on the didReceive method.

bestAttemptContent

The raw version of the received UNMutableNotificationContent, this will be used if the modification fails. This is set on the didReceive method.

didReceive

Overridden method of UNNotificationServiceExtension. It does the following in respective order:

  1. Sets the value for contentHandler and bestAttemptContent
  2. Calls addImageIfNecessary
  3. Calls createSupportedCategory
  4. Sets UNUserNotificationCenter notification categories
  5. Calls the contentHandler

serviceExtensionTimeWillExpire

Overridden method of UNNotificationServiceExtension. This will be triggered if the allotted time (no more than 30 seconds) for the application to modify the notification is about to end. If the modification is not yet finished, this method will call the contentHandler passing the bestAttemptContent.

addImageIfNecessary

Adds an image as an attachment to the passed UNMutableNotificationContent if the notification’s payload includes an “image_url” and has a valid value.

createAction

Builder method that creates an instance of UNNotificationAction depending on the passed RichPushAction.

createCategory

Builder method that creates an instance of UNNotificationCategory depending on the passed RichPushCategory and list of RichPushAction.

createSupportedCategory

Method that creates a RichPushCategory depending on the notification’s payload, then uses it to call another method in this class to create and return a new instance of UNNotificationCategory and set its supported RichPushAction(s).

Other methods

RichPushService method Created RichPushCategory Created RichPushAction(s)
setupChallengeCategory challenge openChallenge
setupContentPageCategory contentPage openContentPage
setupEventFavoriteCategory eventFavorite favoriteEvent
setupOfferCertificateCategory offerCertificate openCertificate
setupOfferClipCategory offerClip clipOffer
setupOfferCouponCategory offerCoupon openCoupon
setupOfferLinkCategory offerLink openOfferLink
setupPostLikeCategory postLike likePost
setupPostLikeCommentCategory postLikeComment likePost, commentPost

Defaults

For protocols NotificationHelper, PushHandler, and RichPushHandler, the kit provides classes that conforms to those protocols and has default implementations that are compatible with most of our supported use cases. These are provided to minimize the bootstrapping when the kit is being integrated into an application. For customization, please refer to Customization section.

DefaultNotificationHelper

pushHandler - Uses DefaultPushHandler

richPushHandler - Uses DefaultRichPushHandler

handleNotificationResponse

  • Executes completionHandler if response.actionIdentifier is UNNotificationDismissActionIdentifier or response.notification.request.content.userInfo cannot be casted as [String: Any]
  • Calls trackMessage if the payload has an Integer value for “message_response_id”
  • Calls pushHandler.handlePush if response.actionIdentifier is UNNotificationDefaultActionIdentifier, otherwise, calls richPushHandler.handleRichPushResponse for Rich Push Notifications

requestAuthorization

  • Calls UNUserNotificationCenter.current().requestAuthorization

registerForRemoteNotifications

  • Calls UIApplication.shared.registerForRemoteNotifications()

trackMessage

  • Calls MessagesAPI.trackMessage

setApplicationBadgeCount

  • Calls UNUserNotificationCenter.current().requestAuthorization passing UNAuthorizationOptions.badge
  • Sets UIApplication.shared.applicationIconBadgeNumber if authorization was granted

DefaultPushHandler

handlePush

  • Calls handleClientEvents if NotificationType is clientEvents and the payload has [Any] value for “client_events”
  • Calls handleContentPageWithName if NotificationType is contentPage and the payload has a non-empty String value for “name”
  • Executes the completionHandler if the payload does not have an Integer value for “id”
  • Calls handleObjectWithId

handleObjectWithId - PROVIDE YOUR OWN

  • The ideal behavior is displaying the detail page of the object

handleNotificationWithoutType - PROVIDE YOUR OWN

  • The ideal behavior is displaying the list of all notifications

handleContentPageWithName - PROVIDE YOUR OWN

  • The ideal behavior is displaying the Content Page

handleClientEvents - PROVIDE YOUR OWN

  • The ideal behavior is displaying the list of Client Events

DefaultRichPushHandler

showMessage - PROVIDE YOUR OWN

  • The ideal behavior is showing an alert with the message

showChallengeResponder - PROVIDE YOUR OWN

  • The ideal behavior is showing a Challenge Response View

showOfferResponseDetail - PROVIDE YOUR OWN

  • The ideal behavior is showing the detail page of the Offer Response

handleRichPushResponse - PROVIDE YOUR OWN

  • Executes the completionHandler if a RichPushAction wasn’t created using the actionIdentifier
  • Calls respective methods depending on RichPushAction and NotificationType. Please refer to the methods below.

handleClipOffer

  • Fetches payload’s Integer value for “id”
  • Calls OffersAPI.clipOffer
  • Executes completionHandler on main queue after the API call

handleCommentPost

  • Fetches payload’s Integer value for “id”
  • Calls NewsFeedAPI.addNewComment
  • Executes completionHandler on main queue after the API call

handleFavoriteEvent

  • Fetches payload’s Integer value for “id”
  • Calls EventsAPI.favoriteEvent
  • Executes completionHandler on main queue after the API call

handleOpenCertificate

  • Fetches payload’s Integer value for “id”
  • Calls OffersAPI.respondToOffer
  • Executes completionHandler on main queue after the API call
  • Copies the certificate’s code on the clipboard
  • Calls showMessage("RichPush.CertificateCodeCopiedToClipboard".localized)

handleOpenChallenge

  • Fetches payload’s Integer value for “id”
  • Calls ChallengesAPI.getChallenge
  • Executes completionHandler on main queue after the API call
  • Calls showChallengeResponder on the main queue after the API call

handleOpenContentPage

  • Fetches payload’s Integer value for “id”
  • Calls ContentAPI.getContentPage
  • Executes completionHandler on main queue after the API call
  • Calls UIApplication.shared.open using the Content Page’s URL if valid

handleOpenCoupon

  • Fetches payload’s Integer value for “id”
  • Calls OffersAPI.respondToOffer
  • Executes completionHandler on main queue after the API call
  • Calls showOfferResponseDetail on the main queue

handleOpenOfferLink

  • Calls OffersAPI.getOffer
  • Calls OffersAPI.respondToOffer after the API call
  • Executes completionHandler on main queue after the initial API call
  • Calls UIApplication.shared.open using the Offer’s URL if valid after the initial API call

handleLikePost

  • Calls NewsFeedAPI.likePost
  • Executes completionHandler on main queue after the API call

Customization

If the provided default implementations do not satisfy your application’s requirements, you have 3 options for customization.

  1. Subclass the default classes and override its methods and/or properties you wish to modify. Though for RichPushService, it is already a subclass, you just need to override its methods.
  2. For protocols NotificationHelper, PushHandler, and RichPushHandler, you can create your own classes that conform to those protocols and use it instead of the defaults.
  3. You can use a combination of your custom classes and the default classes.