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.
- In your project/workspace, go to File -> New -> Target
- Under the iOS tab, look for Notification Service Extension and select it
- Set its name to “NotificationService”
- 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.
- Create a new App Group Identifier
- Set the description to “YourAppName Group”
- Set the Identifier to “group.your.app.bundle.id”
- 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
- In your application’s App ID, enable App Groups and Push Notifications capabilities and use the created App Group on step 1
- 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
-
Import frameworks to use its components
import CheetahDigitalCore import CheetahDigitalNotifications
-
Create a subclass of
DefaultPushHandler
andDefaultRichPushHandler
classes preferably on each of their own filesclass AppPushHandler: DefaultPushHandler { // TODO: Override methods that don’t have default implementations } class AppRichPushHandler: DefaultRichPushHandler { // TODO: Override methods that don’t have default implementations }
-
Create a property that will hold an instance of
DefaultNotificationHelper
in your AppDelegate passing your classes on step 2let notificationHelper = DefaultNotificationHelper(pushHandler: AppPushHandler(), richPushHandler: AppRichPushHandler())
-
Register for remote notifications and set
UNUserNotificationCenterDelegate
in yourAppDelegate
’sdidFinishLaunchingWithOptions
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() } } }) })
-
Send device token to server in
didRegisterForRemoteNotificationsWithDeviceToken
method of yourUNUserNotificationCenterDelegate
notificationHelper.sendDeviceTokenToServerIfNeeded(deviceToken)
-
Handle notification responses in
didReceiveResponse
method of yourUNUserNotificationCenterDelegate
when your application is not activenotificationHelper.handleNotificationResponse(response, completionHandler: completionHandler)
-
Display incoming notification in
willPresentNotification
method of yourUNUserNotificationCenterDelegate
when your application is in foregroundcompletionHandler(.alert)
-
Make your
NotificationService
class that was created here a subclass of the kit’sRichPushService
and remove everything in itclass 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:
- Sets the value for
contentHandler
andbestAttemptContent
- Calls
addImageIfNecessary
- Calls
createSupportedCategory
- Sets
UNUserNotificationCenter
notification categories - 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
ifresponse.actionIdentifier
isUNNotificationDismissActionIdentifier
orresponse.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
ifresponse.actionIdentifier
isUNNotificationDefaultActionIdentifier
, otherwise, callsrichPushHandler.handleRichPushResponse
for Rich Push Notifications
requestAuthorization
- Calls
UNUserNotificationCenter.current().requestAuthorization
registerForRemoteNotifications
- Calls
UIApplication.shared.registerForRemoteNotifications()
trackMessage
- Calls
MessagesAPI.trackMessage
setApplicationBadgeCount
- Calls
UNUserNotificationCenter.current().requestAuthorization
passingUNAuthorizationOptions.badge
- Sets
UIApplication.shared.applicationIconBadgeNumber
if authorization was granted
DefaultPushHandler
handlePush
- Calls
handleClientEvents
ifNotificationType
isclientEvents
and the payload has[Any]
value for “client_events” - Calls
handleContentPageWithName
ifNotificationType
iscontentPage
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 aRichPushAction
wasn’t created using theactionIdentifier
- Calls respective methods depending on
RichPushAction
andNotificationType
. 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.
- 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. - For protocols
NotificationHelper
,PushHandler
, andRichPushHandler
, you can create your own classes that conform to those protocols and use it instead of the defaults. - You can use a combination of your custom classes and the default classes.