Castled provides a convenient way to send push notifications to your applications directly from our dashboard. Follow these steps to send your first push notification to your application:

1. Configure Push Notifications

To enable push notifications on your iOS application using the Castled dashboard, you are required to upload a key or certificate obtained from your Apple Developer account. There are two available methods to configure push notifications.

Refer here for more information on how to obtain .p8 file.

Using APNS Provider Certificate

Refer here for more information on how to obtain .p12 certificate.

2. Enable Push Notification in App Target

  1. Add the Castled framework in General tab

  2. Add Remote Notificaiton as a Background Mode in Signing and Capabilities tab

  3. Add Push Notification cabaility by clicking on + Capability button

3. Code changes for registering Push Notification

In iOS 10 and above, to handle push notifications, you need to implement the following methods from UIApplicationDelegate and UNUserNotificationCenterDelegate protocols:

UIApplicationDelegate Methods:

application(_:didFinishLaunchingWithOptions:) This method is called when the app finishes launching. You can use this method to register for remote notifications and configure the notification settings.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    //1. Configure config
    let config = CastledConfigs.sharedInstance
    config.enablePush  = true
    config.location    = CastledLocation.US

    //2. Set application delegate
     application.delegate = self

    //3. Set UNUserNotificationCenter delegate 
    UNUserNotificationCenter.current().delegate = self

    //4. Call Castled.configure method
    Castled.configure(registerIn: application, launchOptions: launchOptions, instanceId: "<instance_id>", delegate: self)

    //5. Register Push 
    registerForPush()
}

func registerForPush() {
    UNUserNotificationCenter.current().requestAuthorization(options: [.sound, .badge, .alert], completionHandler: {granted, error in
        if granted {
            DispatchQueue.main.async {
                UIApplication.shared.registerForRemoteNotifications()
            }
        }
    })
}

Obtaining user authorization is a crucial requirement for sending push notifications to an iOS application. When your app requests authorization for the first time, the system presents a prompt to the user, giving them the choice to grant or deny the request. The user’s response is then recorded by the system for future reference.

application(_:didRegisterForRemoteNotificationsWithDeviceToken:) This method is called when the app successfully registers for remote notifications with the Apple Push Notification service (APNs). You can use the deviceToken parameter to send push notifications to the device.

func castled_application(_ application: UIApplication,didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    //Invoke the setDeviceToken method if swizzling is off
    Castled.sharedInstance?.setDeviceToken(deviceToken: deviceToken)
}

application(_:didFailToRegisterForRemoteNotificationsWithError:) This method is called when the app fails to register for remote notifications. You can handle the error and take appropriate action.

func castled_application(_ application: UIApplication,didFailToRegisterForRemoteNotificationsWithError error: Error) {
    //Invoke the logRegisterForRemoteNotifications to log the error if swizzling is off
    Castled.sharedInstance!.logRegisterForRemoteNotifications("Failed to register: \(error)")
}

UNUserNotificationCenterDelegate Methods:

userNotificationCenter(_:willPresent:withCompletionHandler:) This method is called when a notification is about to be presented to the user while the app is in the foreground. You can customize the presentation options for the notification, such as showing an alert, playing a sound, or updating the app badge.

func userNotificationCenter(_ center: UNUserNotificationCenter,
                                             willPresent notification: UNNotification,
                                             withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    //Invoke the API to handle the notification in the foreground
    Castled.sharedInstance!.handleNotificationInForeground(notification: notification)

    completionHandler([.badge, .sound, .alert])
}

userNotificationCenter(_:didReceive:withCompletionHandler:) This method is called when the user taps on or interacts with a notification. You can handle the user’s response to the notification, such as opening a specific screen in the app or performing a specific action.

 func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    //Invoke the handleNotificationAction to handle the user actions
    Castled.sharedInstance?.handleNotificationAction(response : response)

    completionHandler()
}

Make sure to set the delegate of the UNUserNotificationCenter instance and the UIApplication instance to your AppDelegate class to receive and handle the push notifications.

Custom handling of User Actions

The Castled SDK provides support for handling custom notification actions when the user interacts with push notifications in your application. By implementing the CastledNotificationDelegate protocol in your AppDelegate class, you can define the behavior for different notification actions such as deeplinking, navigating to a specific screen, or displaying a rich landing page.

CastledNotificationDelegate methods

handleDeepLink(url: URL?, useWebview: Bool, additionalData: [String: Any]?) This method is called when the user selects a notification action with a deeplink type.

  • url : the deeplink URL associated with the action, which you can use to navigate to a specific screen or perform custom logic.
  • useWebview : indicates whether the deeplink should be opened in a webview.
  • additionalData : any additional data associated with the action
// Implement the CastledNotificationDelegate methods
func handleDeepLink(url: URL?, useWebview: Bool, additionalData: [String: Any]?) {
    // Handle deeplink action
    // Navigate to the specified URL or perform custom logic
}

handleNavigateToScreen(screenName: String?, useWebview: Bool, additionalData: [String: Any]?) This method is called when the user selects a notification action to navigate to a specific screen.

  • screenName : the name or identifier of the screen you want to navigate to.
  • useWebview : indicates whether the deeplink should be opened in a webview.
  • additionalData : any additional data associated with the action
func handleNavigateToScreen(screenName: String?, useWebview: Bool, additionalData: [String: Any]?) {
    // Handle navigate to screen action
    // Navigate to the specified screen or perform custom logic
}

handleRichLanding(screenName: String?, useWebview: Bool, additionalData: [String: Any]?) This method is called when the user selects a notification action to display a rich landing page.

  • screenName : he name or identifier of the rich landing screen.
  • useWebview : indicates whether the deeplink should be opened in a webview.
  • additionalData : any additional data associated with the action
func handleRichLanding(screenName: String?, useWebview: Bool, additionalData: [String: Any]?) {
    // Handle rich landing action
    // Display the rich landing page or perform custom logic
}

App Integration to handle user actions

To integrate the Castled SDK and handle custom notification actions, follow these steps:

Step 1: Import the Castled SDK In your AppDelegate file, import the Castled SDK by adding the following import statement at the top of the file:

import Castled

Step 2: Implement the CastledNotificationDelegate In your AppDelegate class, adopt the CastledNotificationDelegate protocol by adding it to the class declaration and implementing its methods. Here’s an example implementation:

@Main
class AppDelegate: UIResponder, UIApplicationDelegate, CastledNotificationDelegate {

    // ...

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Initialize the Castled SDK and other setup
        Castled.configure(registerIn: application, launchOptions: launchOptions, instanceId: "<instance_id>", delegate: self)
        
        // Set the CastledNotificationDelegate
        Castled.sharedInstance?.setCastledNotificationDelegate(self)
        
        // Other didFinishLaunchingWithOptions setup
        
        return true
    }

    // Implement the CastledNotificationDelegate methods
    func handleDeepLink(url: URL?, useWebview: Bool, additionalData: [String: Any]?) {
        // Handle deeplink action
        // Navigate to the specified URL or perform custom logic
    }

    func handleNavigateToScreen(screenName: String?, useWebview: Bool, additionalData: [String: Any]?) {
        // Handle navigate to screen action
        // Navigate to the specified screen or perform custom logic
    }

    func handleRichLanding(screenName: String?, useWebview: Bool, additionalData: [String: Any]?) {
        // Handle rich landing action
        // Display the rich landing page or perform custom logic
    }

    // ...
}

Step 3: Configuring Custom Actions in the Castled Dashboard In the Castled dashboard, configure your push notifications with custom actions. Specify the action type (deeplink, navigate to screen, or rich landing), and provide any additional data required for each action. Make sure the details passed match the implementation details in the methods you implemented in the CastledNotificationDelegate.

Configuring Notification Categories and Actions

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 App

During app launch, you can register all notification categories together using the setNotificationCategories: method of the shared UNUserNotificationCenter object. Prior to calling this method, you need to create one or more instances of the UNNotificationCategory class. Each category instance should include the category name and options that determine how notifications of that type should be displayed.

Category names are internal to your app and remain invisible to the user. When scheduling notifications, you include the corresponding category name in the notification payload. The system then uses this category name to retrieve the associated options and properly display the notification.

@main
class AppDelegate: UIResponder, UIApplicationDelegate , UNUserNotificationCenterDelegate {
    var window: UIWindow?
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        // Register the Custom Notification categories & actions
        let notificationCategories = getNotificationCategories();
        UNUserNotificationCenter.current().setNotificationCategories(notificationCategories)

        return true
    }

    func getNotificationCategories() -> Set<UNNotificationCategory>{
        // Create the custom actions
        let action1 = UNNotificationAction(identifier: "ACCEPT", title: "Accept", options: UNNotificationActionOptions.foreground)
        let action2 = UNNotificationAction(identifier: "DECLINE", title: "Decline", options: [])
        
        // Create the category with the custom actions
        let customCategory1 = UNNotificationCategory(identifier: "ACCEPT_DECLINE", actions: [action1, action2], intentIdentifiers: [], options: [])
        
        let action3 = UNNotificationAction(identifier: "YES", title: "Yes", options: [UNNotificationActionOptions.foreground])
        let action4 = UNNotificationAction(identifier: "NO", title: "No", options: [])
        
        // Create the category with the custom actions
        let customCategory2 = UNNotificationCategory(identifier: "YES_NO", actions: [action3, action4], intentIdentifiers: [], options: [])
        
        let categoriesSet = Set.init([customCategory1,customCategory2])
        
        return categoriesSet;
    }
}

The UNNotificationActionOptions.foreground option is used to specify the behavior of a notification action when it is clicked by the user. Make sure this option is included, so that the action launches the application and bring it to the foreground.