Enabling Push Notification in SDK
SetenablePush to true during SDK initialization. More details about SDK initialization can be found
here
// Set config
const configs = new CastledConfigs()
configs.appId = "<app-id>"
configs.location = CastledLocation.US
configs.enablePush = true
configs.appgroupId = '<your_ios_appgroup_id>'
// Initialize SDK
CastledNotifications.initialize(configs)
Native setup
- Android
- iOS
Step 1: Add required permissions
Add the following permission to android appAndroidManifest.xml. This allows the app to receive push notificationsAndroidManifest.xml
<manifest ...>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<application ...>
...
</application>
</manifest>
Step 2: Firebase push messaging handling service
By default SDK takes care of push token fetch and notification handling once app gets the permission to post notification. In case the app has registered its own Firebase message service class (FirebaseMessagingService) for handling push tokens,
SDK needs to be notified of the new token and any push notification received from Castled platform.
Folow these instructions
if you already have a FirebaseMessagingService registered.Step 3: Notification default configs
You can also configure default values for Notification Channels and Notification Icons. Please find the instructions hereStep 1: Configure App Target for iOS Push
Follow these instructions for app target setup.Ensure the appgroupId mentioned above matches the one enabled in the App Groups section of the Signing & Capabilities tab for all relevant targets in Xcode, including extensions. If App Groups are not enabled, there is no need to set an appgroupId.We recommend configuring the appgroupId and using the Notification Service Extension for enhanced tracking of notification impressions, accurate badge counts, and media support.
Step 2: Configuring Notification Categories and Actions (Optional)
Apps are required to enable support for actionable notifications. During app launch, it is necessary to register one or more notification categories that define the types of notifications your app sends. Each category is associated with specific actions that users can take when receiving a notification of that type. While each category can have up to four actions, the actual number of displayed actions may vary depending on the notification display. For instance, banners typically show a maximum of two actions.Registering the Notification Categories for Your AppBy passing the notificationCategories parameter, you can define a set of categories and associated actions for your notifications. Each category corresponds to a type of notification that your app can receive, and for each category, you can specify the actions that a user can take directly from the notification.This flexibility allows app developers to create a rich and interactive notification experience, tailored to the needs of their application and its users.// Import any of the below depending on whether the castled-react-native-sdk is provided as a static library or a dynamic library:
#import "CastledReactBridge.h"
// OR
#import <castled-react-native-sdk/CastledReactBridge.h>
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.moduleName = @"TestApp";
// You can add your custom initial props in the dictionary below.
// They will be passed down to the ViewController used by React Native.
self.initialProps = @{};
[[CastledReactBridge sharedInstance] setNotificationCategoriesWithItems:[self getNotificationCategories]];
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
- (NSSet<UNNotificationCategory *> *)getNotificationCategories {
// Create the custom actions
UNNotificationAction *action1 = [UNNotificationAction actionWithIdentifier:@"ACCEPT" title:@"Accept" options:UNNotificationActionOptionForeground];
UNNotificationAction *action2 = [UNNotificationAction actionWithIdentifier:@"DECLINE" title:@"Decline" options:0];
// Create the category with the custom actions
UNNotificationCategory *customCategory1 = [UNNotificationCategory categoryWithIdentifier:@"ACCEPT_DECLINE" actions:@[action1, action2] intentIdentifiers:@[] options:0];
UNNotificationAction *action3 = [UNNotificationAction actionWithIdentifier:@"YES" title:@"Yes" options:UNNotificationActionOptionForeground];
UNNotificationAction *action4 = [UNNotificationAction actionWithIdentifier:@"NO" title:@"No" options:0];
// Create the category with the custom actions
UNNotificationCategory *customCategory2 = [UNNotificationCategory categoryWithIdentifier:@"YES_NO" actions:@[action3, action4] intentIdentifiers:@[] options:0];
NSSet<UNNotificationCategory *> *categoriesSet = [NSSet setWithObjects:customCategory1, customCategory2, nil];
return categoriesSet;
}
Step 3: Support for Rich Push Notification
Follow the instructions here for setting up rich push notifications.Also in the /ios directory of your project, open the Podfile and add the following outside of the main target (should be at the same level as your main target):target 'CastledNotificationServiceExtension' do
pod 'CastledNotificationService'
end
target 'CastledNotificationContentExtension' do
pod 'CastledNotificationContent'
end
We recommend configuring the appgroupId and using the Notification Service Extension for enhanced tracking of notification impressions, accurate badge counts, and media support.
Step 4: AppDelegate Swizzling in Castled SDK
Castled SDK is designed to simplify push notification handling. By default, swizzling is enabled, which means the SDK automatically handles the registration of device tokens, the presentation of notifications, and the response to user interactions with those notifications.Disable SwizzlingThis step is applicable only if:- Your app is using other SDKs along with Castled for handling push notification.
- You prefer to have more granular control over notification handling or may need to comply with specific architectural requirements.
info.plist
<key>CastledSwizzlingDisabled</key>
<true/>
UNUserNotificationCenterDelegate and UIApplicationDelegate methods to handle
different notification scenarios.Manual Handling of Push Notifications
Initializing Castled React SDK and Setting Delegates #import "AppDelegate.h"
// 1: Import the Castled React SDK
#import "CastledReactBridge.h"
#import <UserNotifications/UserNotifications.h>
// 2: Declare AppDelegate conforming to UIApplicationDelegate and UNUserNotificationCenterDelegate protocols to manage notifications.
@interface AppDelegate ()<UIApplicationDelegate,UNUserNotificationCenterDelegate>
{
}
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.moduleName = @"Module Name";
// 3: Assign AppDelegate as the delegate for UNUserNotificationCenter to handle notification events
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
// You can add your custom initial props in the dictionary below.
// They will be passed down to the ViewController used by React Native.
self.initialProps = @{};
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
If your Swift project doesn’t have a bridging header yet, you need to create one. To acheive this,
Create a new Objective-C file in your Swift project. Xcode will prompt you to create a bridging header.
Accept and let Xcode create it.
// Handling Device Token Registration
-(void) application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
NSMutableString *deviceTokenString =[NSMutableString string];
if (@available(iOS 13.0, *)) {
deviceTokenString = [NSMutableString string];
const unsigned char *bytes = (const unsigned char *)[deviceToken bytes];
NSInteger count = deviceToken.length;
for (int i = 0; i < count; i++) {
[deviceTokenString appendFormat:@"%02x", bytes[i]&0x000000FF];
}
} else {
NSString *deviceToken1 = [[[[deviceToken description]
stringByReplacingOccurrencesOfString:@"<" withString:@""]
stringByReplacingOccurrencesOfString:@">" withString:@""]
stringByReplacingOccurrencesOfString:@" " withString:@""];
deviceTokenString = [[NSMutableString alloc] initWithString:deviceToken1];
}
NSLog(@"didRegisterForRemoteNotificationsWithDeviceToken: %@", deviceTokenString);
[[CastledReactBridge sharedInstance] setPushToken:deviceTokenString type: apns];
}
// Handling Registration Failure
-(void) application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
NSLog(@"failed to register for remote notifications: %@ %@", self.description, error.localizedDescription);
}
// Handling Notification Responses
-(void) userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
[[CastledReactBridge sharedInstance] userNotificationCenter:center didReceiveNotificationResponse:response];
completionHandler();
}
// Handling Foreground Notification Presentation
-(void) userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
[[CastledReactBridge sharedInstance] userNotificationCenter:center willPresentNotification:notification];
if (@available(iOS 14.0, *)) {
// For iOS 14 and later
completionHandler(UNNotificationPresentationOptionBanner | UNNotificationPresentationOptionList | UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound);
} else {
// For iOS 13 and earlier
completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound);
}
}
// Handling Background Notifications
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
[[CastledReactBridge sharedInstance] didReceiveRemoteNotification:userInfo];
// Implement your logic here...
completionHandler(UIBackgroundFetchResultNoData);
}
If the App is handling the push notification click actions itself, please
disable the default url handling by the SDK by setting
skipUrlHandling to
true in the SDK configs during initialization.Requesting Push Notification Permission
Following SDK method can be used by the app to fetch user permission for showing push notifications. User will be shown the native notification permission dialog based on the mobile platform he is on.CastledNotifications.requestPushPermission()
.then((isGranted) => {
if (isGranted) {
console.log("Push notification permission granted")
} else {
console.log("Push notification permission not granted")
}
})
.catch((error) => {
console.log("Request failed, error: " + error.message)
})
Push Notification Events Listener
App can listen to push notification events by registering a listener. This is useful when you want to override the default click actions implemented by the SDK with your own custom implementations. Currently the following push events as supported:- Notification Received
- Notification Clicked
- Notification Dimissed
import {
CastledEvents,
type CastledClickAction,
type CastledPushNotification,
type CastledPushNotificationClickEvent,
} from "castled-react-native-sdk"
// Push received listener
const pushReceivedListener = CastledNotifications.addListener(
CastledEvents.PUSH_NOTIFICATION_RECEIVED,
(notification: CastledPushNotification) => {
console.log("Push notification received:", notification)
}
)
// Click action listener
const pushClickedListener = CastledNotifications.addListener(
CastledEvents.PUSH_NOTIFICATION_CLICKED,
(event: CastledPushNotificationClickEvent) => {
console.log(
"Push notification clicked: notification object ",
event.notification
)
console.log("Push notification clicked: clickAction", event.clickAction)
}
)
// Push dismissed listener
const pushDismissedListener = CastledNotifications.addListener(
CastledEvents.PUSH_NOTIFICATION_DISMISSED,
(notification: CastledPushNotification) => {
console.log("Push notification dismissed:", notification)
}
)
// Unsubscribing the listeners
pushReceivedListener.remove()
pushClickedListener.remove()
pushDismissedListener.remove()
If the App is handling the push notification click actions itself, please
disable the default url handling by the SDK by setting
skipUrlHandling to
true in the SDK configs during initialization.