Notifications (BrandMessengerCore Custom UI)
Learn about notifications using the Brand Messenger UI
Build your UI from scratch - Message Notification
This section describes how to receive push notifications for your chat within your app.
Setting up APNs Certificates
Brand Messenger server sends the payload to Apple servers which then sends push notifications to your user's device.
Creating APNs certificates
For Apple to send these notifications, you must create an APN certificate in your Apple developer account.
- Visit this link, Apple Push Notification service SSL (Sandbox)
- Visit this link, select Apple Push Notification service SSL (Sandbox & Production), and click Create.
Note: Supported format for the APNS certificate is .p12
The p12 files are required to for authentication with Apple servers and for sending APNs push notifications to devices. This section shows you how to export p12 file from Keychains for uploading to the Brand Messenger.
Follow these steps for export Apple push service and APNs Development iOS certificate p12 file:
For Apple push service export :
A. Open Keychain Access on your Mac and go to login > Select My Certificates.
B. Find the Apple push services certificate and which you added, right-click on the certificate, and then select the Export option from the menu to get a .p12 file. Type a name for the file and save it with the password.
For APNs Development iOS export :
A. Open Keychain Access on your Mac and go to login > Select My Certificates.
B. Find the APNs Development iOS certificate and which you added, right-click on the certificate, and then select the Export option from the menu to get a .p12 file. Type a name for the file and save it with the password.
Upload APNs Certificates
Contact Khoros Support and provide the exported p12 files with password to upload the notification certificates.
Updating Capabilities
After you finish setting up APNs, you must enable push notifications within your project.
Click on your project, click Capabilities, and select Enable.
- Push Notifications
- Background Modes - Fetch and Remote notification
Push Notifications
To set up push notification, find the "AppDelegate" file in your project and follow the instructions below.
Setup BrandMessengerClient
Note: You need to setup BrandMessengerClient before using the methods refer to this link
a) Send device token to Brand Messenger server:
In your AppDelegate’s didRegisterForRemoteNotificationsWithDeviceToken method, send device registration to BrandMessenger server after you get deviceToken from APNs.
- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)
deviceToken {
const unsigned *tokenBytes = [deviceToken bytes];
NSString *hexToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
NSString *apnDeviceToken = hexToken;
NSLog(@"apnDeviceToken: %@", hexToken);
if (![[KBMUserDefaultsHandler getApnDeviceToken] isEqualToString:apnDeviceToken]) {
KBMRegisterUserClientService *registerUserClientService = [[KBMRegisterUserClientService alloc] init];
[registerUserClientService updateApnDeviceTokenWithCompletion
:apnDeviceToken withCompletion:^(KBMRegistrationResponse
*rResponse, NSError *error) {
if (error) {
NSLog(@"%@",error);
return;
}
NSLog(@"Registration response%@", rResponse);
}];
}
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
NSLog("Device token data :: \(deviceToken.description)")
var deviceTokenString: String = ""
for i in 0..<deviceToken.count {
deviceTokenString += String(format: "%02.2hhx", deviceToken[i] as CVarArg)
}
NSLog("Device token :: \(deviceTokenString)")
if (KBMUserDefaultsHandler.getApnDeviceToken() != deviceTokenString) {
let registerUserClientService: KBMRegisterUserClientService = KBMRegisterUserClientService()
registerUserClientService.updateApnDeviceToken(withCompletion: deviceTokenString, withCompletion: { (response, error) in
if error != nil {
NSLog("Error in Registration: %@", error)
}
NSLog("Registration Response :: \(response)")
})
}
}
b) Handling app launch on notification:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[KBMRegisterUserClientService isAppUpdated];
if (launchOptions != nil) {
NSDictionary *dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (dictionary != nil) {
NSLog(@"Launched from push notification: %@", dictionary);
[self.brandMessengerClient notificationArrivedToApplication:application withDictionary:dictionary];
}
}
return YES;
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
KBMRegisterUserClientService.isAppUpdated()
if (launchOptions != nil) {
let dictionary = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? NSDictionary
if (dictionary != nil) {
brandMessengerClient?.notificationArrived(to: application, with: launchOptions)
}
}
return true
}
c) AppDelegate changes to observe background/foreground notification:
Background Notification
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler{
[self.brandMessengerClient notificationArrivedToApplication:application withDictionary:userInfo];
completionHandler(UIBackgroundFetchResultNewData);
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
KBMPushNotificationService * service = [[KBMPushNotificationService alloc]init];
NSDictionary * userInfo = response.notification.request.content.userInfo;
if ([service isBrandMessengerChatNotification: userInfo]) {
[self.brandMessengerClient notificationArrivedToApplication:[UIApplication sharedApplication] withDictionary:response.notification.request.content.userInfo];
completionHandler();
} else {
//Handle your noticiation
completionHandler();
}
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler
completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print("Received notification With Completion :: \(userInfo.description)")
brandMessengerClient?.notificationArrived(to: application, with: userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
let service = KBMPushNotificationService()
if service.isBrandMessengerChatNotification(userInfo) {
brandMessengerClient?.notificationArrived(to: UIApplication.shared, with: userInfo)
completionHandler()
return
}
completionHandler()
}
d) Add the code shown below into applicationWillEnterForeground of appDelegate to sync messages
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
[KBMMessageService getLatestMessageForUser:[KBMUserDefaultsHandler getDeviceKeyString] withDelegate:self withCompletion:^(NSMutableArray *messages, NSError *error) {
}];
}
func applicationDidBecomeActive(_ application: UIApplication) {
KBMMessageService.getLatestMessage(forUser: KBMUserDefaultsHandler.getDeviceKeyString(), with: self) { (array, error) in
}
}
if messages
are there, you can add messages in your view controller after the messages are synced.
e) Save Context when app terminates
- (void)applicationWillTerminate:(UIApplication *)application {
[[KBMDBHandler sharedInstance] saveContext];
}
func applicationWillTerminate(application: UIApplication) {
KBMDBHandler.sharedInstance().saveContext()
}
Disable Notification
To disable the incoming push notification alert or only notification sound, you need to update notification mode. The possible values for the notification mode are shown below.
[KBMRegisterUserClientService updateNotificationMode:modeValue withCompletion:^(KBMRegistrationResponse *response, NSError *error) {
NSLog(@"RESPONSE :: %@",response.message);
NSLog(@"RESPONSE_ERROR :: %@",error.description);
if (!error) {
[KBMUserDefaultsHandler setNotificationMode:modeValue];
} else {
//Error updating notification mode...
}
}];
KBMRegisterUserClientService.updateNotificationMode(modeValue, withCompletion: {
response, error in
if (error != nil) {
//Error updating notification mode...
} else {
KBMUserDefaultsHandler.setNotificationMode(modeValue)
}
})
Notification Mode | Explanation |
---|---|
0 | Enable notification with sound (Default) |
1 | Enable notification without sound |
2 | Disable notification (No Alert) |
Custom Push Notification messages
When using generic push-notifications, the SDK Provides a way for the developer to customize the title and text of the incoming push-notification displayed in the iOS Banner.
This requires the following steps.
1) Create new Notification Service Extension target
From Xcode, in project TARGETS
, add a new target of type Notification Service Extension
.
Official instructions are https://developer.apple.com/documentation/usernotifications/modifying_content_in_newly_delivered_notifications?language=objc
This will create a new NotificationService
file.
2) Update NotificationService file
Update the file to look like the following
import UserNotifications
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)
if let bestAttemptContent = bestAttemptContent {
// Modify the notification content here...
/// Brand messenger notification
if isBrandMessengerChatNotificaiton(content: request.content) {
bestAttemptContent.title = NSLocalizedString("GenericNotificationTitle", tableName: nil, bundle: .main, value: "Chat", comment: "")
bestAttemptContent.body = NSLocalizedString("GenericNotificationContentText", tableName: nil, bundle: .main, value: "You have a new message.", comment: "")
}
contentHandler(bestAttemptContent)
}
}
override func 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 let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
/// Use this method to check for notification for Brand Messenger.
/// - Parameter content:Pass `UNNotificationContent` object for notification userInfo payload.
/// - Returns: Returns `true` if it's a Brand Messenger notification otherwise `false`.
func isBrandMessengerChatNotificaiton(content: UNNotificationContent) -> Bool {
let prefix = "BRANDMESSENGER_"
let notificationKey = "AL_KEY"
guard let brandMessengerPrefix = content.userInfo[notificationKey] as? String, brandMessengerPrefix.hasPrefix(prefix) else {
return false
}
return true
}
}
3) Bundle Localizable.strings into the created extension
In Xcode, in Project settings, select the newly created Notification Service Extension
TARGET
. Go to Build Phases
tab, and in Copy Bundle Resources
, add the app's Localizable.strings
file. If one does not already exist, create one and add.
4) Modify the notification strings
In the Localizable.strings
file, add values for GenericNotificationTitle
and GenericNotificationContentText
to set them on the incoming push-notification banners.
GenericNotificationTitle = "Khoros Chat";
GenericNotificationContentText = "You have a new message!";
Updated over 1 year ago