iOS
Push Notifications

Push Notifications for iOS

Push notifications for iOS client apps are sent using Apple Push Notification service (APNs). They are used for keeping your users informed with timely and relevant content, whether your client app is running in the background or inactive on a device. They can also perform the types of user interactions such as alert, sound, or badge, and include custom data your app needs to respond to the notifications.

Our iOS SDK enables you to build a client app that can receive push notifications. When a message is sent to SendBird server through the SDK, the server communicates with APNs regarding the message and then APNs delivers a push notification for the message to an iOS device where your client app is installed.

Note: By default, when a user to receive messages is being disconnected from SendBird server, the server sends notification requests to APNs for the messages. The iOS SDK automatically detects when a user's client app goes into the background, and updates the user's connection status to disconnected. Therefore, in normal cases, you don't need to call the disconnectWithCompletionHandler: method explicitly.

This page mainly describes how to obtain iOS and APNs credentials from the Apple Developer portal and how to setup your iOS client app with the SDK to receive push notifications. The following steps in this page are written on the assumption that you already have an app ID assigned to your client app.

Note: Push notifications are supported in group channels only, and are not avaliable in open channels.


Step 1: Create your certificate signing request

To obtain a signing certificate required to sign apps for installation on iOS devices, you should first create a certificate signing request (CSR) file through Keychain Access on your Mac.

  1. Open the Keychain Access from the Utilities folder, go to Keychain Access > Certificate Assistant > Request a Certificate From a Certificate Authority, and then click.
    CSR1
  2. The Certificate Information dialog box appears. Enter the email address that you use in your Apple Developer account, and enter a common name for your private key. Don't enter CA email address, choose Saved to disk, and then click the Continue button.
    CSR2
  3. Specify the name of your CSR to save and choose the location to save the file on your local disk. Then your CSR file is created, which contains a public/private key pair.

Step 2: Create your push notification SSL certificate

  1. Sign in to your account at the Apple Developer Member Center and choose Certificates, Identifiers & Profiles. In the Identifiers > App IDs, select the Push Notifications service under Application Services, and then click the Edit button.
    App IDs
  2. Under the Push Notifications service, choose which SSL certificate to create either Development or Production.
    Push Certificate
  3. In the Generate your certificate pane that appears after the selection, under Upload CSR file., upload the CSR file you created through the Choose File... button. To complete the process, choose Continue. When the certificate is ready, choose Download to save it to your Mac.
    Push Certificate
  4. In order to install the downloaded certificate to the KeyChain Access on your Mac, double-click it. You can find the certificate in the KeyChain Access > login > Certificates.

Step 3: Export a .p12 file and upload to SendBird Dashboard

To send notification requests to APNs on behalf of your server, SendBird server needs your .p12 file containing the certificates which Apple requires to build and publish your client app. To communicate with APNs, the server uses just some of the credential information in your .p12 file.

You can register your .p12 file to the server through SendBird Dashboard or by using the platform API's add an APNs push configuration action. The following shows how to register using the dashboard.

  1. Under KeyChain Access > login > Certificates, find the push notification SSL certificate you just added, right-click the certificate, then select Export... from the context menu to export a file containing the certificate.
    P12 export1
  2. Type a name for the .p12 file and save it to your Mac. Do not provide an export password when prompted. Then sign in to your dashboard and upload the file under Settings > Application > Notifications tab.
    Set Push Information

Step 4: Register a device token to SendBird server

When requested to send push notifications to a specific client app on an iOS device, APNs requires the app instance's globally-unique and app-specific device token which has been issued by itself. Therefore, to send notification requests to APNs on behalf of your server, SendBird server needs every device tokens of your client app instances.

If an app instance is successfully registered to APNs via the registerForRemoteNotifications method, a device token is passed to an app delegate object's application:didRegisterForRemoteNotificationsWithDeviceToken: method which is called by the app. Like the following sample code, you should register this token to SendBird server by passing it as a parameter to the registerDevicePushToken:unique:completionHandler: method.

Objective-C
Swift
Light Color Skin
Copy
// AppDelegate.m
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
    // Register a device token to SendBird server.
    [SBDMain registerDevicePushToken:DEVICE_TOKEN unique:YES completionHandler:^(SBDPushTokenRegistrationStatus status, SBDError * _Nullable error) {
        if (error == nil) {
            if (status == SBDPushTokenRegistrationStatusPending) {
                // A token registration is pending.
                // If this status is returned, invoke `+ registerDevicePushToken:unique:completionHandler:` with `[SBDMain getPendingPushToken]` after connection.
            }
            else {
                // A device token is successfully registered.
            }
        }
        else {
            // Registration failure.
        }
    }];
}
Light Color Skin
Copy
// AppDelegate.swift
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    // Register a device token to SendBird server.
    SBDMain.registerDevicePushToken(DEVICE_TOKEN, unique: true) { (status, error) in
        if error == nil {
            if status == SBDPushTokenRegistrationStatus.pending {
                // A token registration is pending.
                // If this status is returned, invoke `+ registerDevicePushToken:unique:completionHandler:` with `[SBDMain getPendingPushToken]` after connection.
            }
            else {
                // A device token is successfully registered.
            }
        }
        else {
            // Registration failure.
        }
    }
}

Note: If SBDPushTokenRegistrationStatusPending is returned through the completionHandler:, this means that your user is not being connected to SendBird server when the registerDevicePushToken:unique:completionHandler: is called. In this case, we recommend that you first get a pending device token by using the getPendingPushToken, and then register the token by invoking the registerDevicePushToken:unique:completionHandler: in a callback of the connectWithUserId:completionHandler: or connectWithUserId:accessToken:completionHandler: when your user has been connected to the server afterward.

Objective-C
Swift
Light Color Skin
Copy
[SBDMain connectWithUserId:USER_ID completionHandler:^(SBDUser * _Nullable user, SBDError * _Nullable error) {
    if (error == nil) {
        [SBDMain registerDevicePushToken:[SBDMain getPendingPushToken] unique:YES completionHandler:^(SBDPushTokenRegistrationStatus status, SBDError * _Nullable error) {

        }];
    }
}];
Light Color Skin
Copy
SBDMain.connect(withUserId: USER_ID, completionHandler: { (user, error) in 
    if error == nil {
        SBDMain.registerDevicePushToken(SBDMain.getPendingPushToken()!, unique: true, completionHandler: { (status, error) in

        })
    }
})

Make sure you call the following code in the appropriate place to receive permissions from your users.

Objective-C
Swift
Light Color Skin
Copy
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
    UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
    [[UIApplication sharedApplication] registerForRemoteNotifications];
} else {
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
Light Color Skin
Copy
let notificationSettings = UIUserNotificationSettings(types: [UIUserNotificationType.alert, UIUserNotificationType.badge, UIUserNotificationType.sound], categories: nil)
    UIApplication.shared.registerUserNotificationSettings(notificationSettings)
    UIApplication.shared.registerForRemoteNotifications()

Step 5: Handle a notification message payload

SendBird server sends notification requests to APNs with the following options:

  • alert: {Sender's nickname}: {Text message}
  • sound: the default alert sound of iOS
  • badge: the total number of each user's unread messages (you can turn off this count from your dashboard.)

The server also sends an additional JSON object with the sendbird key. For notification requests, APNs then delivers push notifications to iOS devices. At the client side, you can parse the data payload and handle the result to implement user reactions within the application:didReceiveRemoteNotification:fetchCompletionHandler: method, which covers all notification messages from the application states of inactive, foreground, and background.

Objective-C
Swift
Light Color Skin
Copy
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler{

    NSString *alertMsg = [[userInfo objectForKey:@"aps"] objectForKey:@"alert"];
    NSDictionary *payload = [userInfo objectForKey:@"sendbird"];
    
    // Implement your custom way to parse payload
    if (application.applicationState == UIApplicationStateInactive) {
        // Receiving a notification message while your app is inactive. 
    } else {
        // Receiving a notification message while your app is in either foreground or background. 
    }   

    completionHandler(UIBackgroundFetchResultNewData);
}
Light Color Skin
Copy
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    let alertMsg = (userInfo["aps"] as! NSDictionary)["alert"] as! NSDictionary
    let payload = userInfo["sendbird"] as! NSDictionary

    // Implement your custom way to parse payload
    if (application.applicationState == .inactive) {
        // Receiving a notification message while your app is inactive. 
    } else {
        // Receiving a notification message while your app is in either foreground or background. 
    }   
 
    completionHandler(UIBackgroundFetchResult.newData)
}

The following is a complete payload format of the sendbird object, which contains a set of provided key-value pairs.

Light Color Skin
Copy
{
    category: "messaging:offline_notification",
    type: string,                   // Message type: 'User', 'File', or 'Admin'
    message: string,                // User input message
    data: string,                   // Custom data field
    custom_type: string,            // Custom message type
    message_id: long,               // Message ID
    created_at: long,               // 13-digit timestamp
    app_id: string,                 // Application's unique ID 
    unread_message_count: int,      // Total unread count of the user
    channel: {
        channel_url: string,        // Group channel URL
        name: string,               // Group channel name
        custom_type: string         // Group channel custom_type
    },
    channel_type: string,           // Channel type: 'messaging', 'group_messaging', or 'chat'
    sender: {
        id: string,                 // Sender's unique ID
        name: string,               // Sender's nickname
        profile_url: string         // Sender's profile image URL 
    },
    recipient: {
        id: string,                 // Recipient's unique ID
        name: string                // Recipient's nickname
    },
    files: [],                      // If a message is a file link, this array represents files.
    translations: {},               // If a message has translations, this dict has locale:translation.
    push_alert: string,             // Customized alert push message
    push_sound: string,             // The location of a sound file for push notifications
    audience_type: string,          // The type of audiences to receive push notifications
    mentioned_users: {
        user_id: string,                    // The ID of a mentioned user
        total_unread_mention_count: int,    // The number of messages which a user has been mentioned but has not read within the channels
        channel_unread_mention_count: int,  // The number of channels with messages which a user has been mentioned but has not read
        is_hidden: boolean                  // Whether or not a mentioned user has hidden the channel from the list
    }
}

Notification preferences

The following shows how to register and unregister the current user's registration token to SendBird server to enable and disable push notifications in the user's client app.

Note: The registration/unregistration methods in the code below should be called after a user has established a connection with SendBird server via the connection methods such as connectionWithUserId:completionHandler: or connectionWithUserId:accessToken:completionHandler:.

Objective-C
Swift
Light Color Skin
Copy
- (void)setPushNotification:(BOOL)enable {
    if (enable) {
        [SBDMain registerDevicePushToken:[SBDMain getPendingPushToken] unique:YES completionHandler:^(SBDPushTokenRegistrationStatus status, SBDError * _Nullable error) {
            if (error != nil) { // Error.
                return;
            }
        }];
    }
    else {
        // If you want to unregister the current device only, invoke this method.
        [SBDMain unregisterPushToken:[SBDMain getPendingPushToken] completionHandler:^(NSDictionary * _Nullable response, SBDError * _Nullable error) {
            if (error != nil) { // Error.
                return;
            }
        }];

        // If you want to unregister the all devices of the user, invoke this method.
        [SBDMain unregisterAllPushTokenWithCompletionHandler:^(NSDictionary * _Nullable response, SBDError * _Nullable error) {
            if (error != nil) { // Error.
                return;
            }
        }];
    }
}
Light Color Skin
Copy
func setPushNotification(enable: Bool) {
    if enable {
        SBDMain.registerDevicePushToken(SBDMain.getPendingPushToken()!, unique: true, completionHandler: { (status, error) in
            if error != nil { // Error.
                return
            }
        })
    }
    else {
        // If you want to unregister the current device only, invoke this method.
        SBDMain.unregisterPushToken(SBDMain.getPendingPushToken()!, completionHandler: { (response, error) in
            if error != nil { // Error.
                return
            }
        })

        // If you want to unregister the all devices of the user, invoke this method.
        SBDMain.unregisterAllPushToken(completionHandler: { (response, error) in
            if error != nil { // Error.
                return
            }
        })
    }
}

If needed, at the current user's client app, you can determine the type of push notification trigger to customize when to deliver notifications. For customization, the SBDPushTriggerOption provides the following three options:

  • SBDPushTriggerOptionAll: the user receives push notifications for all new messages while offline, including mentioned messages.
  • SBDPushTriggerOptionOff: no push notifications are delivered to the user.
  • SBDPushTriggerOptionMentionOnly: the user receives push notifications only for the mentioned messages while offline.
Objective-C
Swift
Light Color Skin
Copy
// If you want to trigger push notifications only when the current user is mentioned in messages.
[SBDMain setPushTriggerOption:SBDPushTriggerOptionMentionOnly completionHandler:^(SBDError * _Nullable error) {
    if (error != nil) { // Error.
        return; 
    }
}];
Light Color Skin
Copy
// If you want to trigger push notifications only when the current user is mentioned in messages.
SBDMain.setPushTriggerOption(SBDPushTriggerOptionMentionOnly, completionHandler: { (error) in
    if error != nil {   // Error.
        return
    }
})

At the channel level, you can also determine the type of push notification trigger by individual channel, and turn on or off notifications for the channel. For this, the SBDGroupChannelPushTriggerOption provides the following four options:

  • SBDPushTriggerOptionAll: the user receives push notifications for all new messages in the channel while offline, including mentioned messages.
  • SBDPushTriggerOptionOff: no push notifications are delivered to the channel.
  • SBDPushTriggerOptionMentionOnly: the user receives push notifications only for the mentioned messages while offline.
  • SBDPushTriggerOptionDefault: the user's push notification trigger setting automatically applies to the channel.
Objective-C
Swift
Light Color Skin
Copy
// If you want to automatically apply the user's push notification setting to the channel.
[channel setMyPushTriggerOption:SBDPushTriggerOptionDefault completionHandler:^(SBDError * _Nullable error) {
    if (error != nil) { // Error.
        return;
    }

    // If you want to turn off push notifications for this channel, pass `false` as a parameter. By default, they are turned on for a channel (true).
    [channel setPushPreferenceWithPushOn:NO completionHandler:^(SBDError * _Nullable error) {
        if (error != nil) { // Error.
            return;
        }
    }];
}];
Light Color Skin
Copy
// If you want to automatically apply the user's push notification setting to the channel.
channel.setMyPushTriggerOption(SBDPushTriggerOptionDefault, completionHandler: { (error) in
    if error != nil {   // Error.
        return
    }

    // If you want to turn off push notifications for this channel, pass `false` as a parameter. By default, they are turned on for a channel (true).
    channel.setPushPreferenceWithPushOn(false) { (error) in
        if error != nil {   // Error.
            return
        }
    }
})

If you want to suppress push notifications on the current user's client app during specific time of every day, use our Do Not Disturb feature like the following.

Note: You can also set a user's Do Not Disturb with the platform API's update push preferences action.

Objective-C
Swift
Light Color Skin
Copy
// The current user will not receive push notifications during the specified time of every day.
[SBDMain setDoNotDisturbWithEnable:YES startHour:START_HOUR startMin:START_MIN endHour:END_HOUR endMin:END_MIN timezone:TIMEZONE completionHandler:^(SBDError * _Nullable error) {
    if (error != nil) { // Error.
        return;
    }
}];
Light Color Skin
Copy
// The current user will not receive push notifications during the specified time of every day.
SBDMain.setDoNotDisturbWithEnable(true, startHour: START_HOUR, startMin: START_MIN, endHour: END_HOUR, endMin: END_MIN, timezone: TIMEZONE, completionHandler: { (error) in
    if error != nil {   // Error.
        return
    }    
})

If you want to snooze push notifications for specific period of time, use our snooze feature like the following.

Note: You can also snooze the notifications for a user with the platform API's update push preferences action.

Objective-C
Swift
Light Color Skin
Copy
// The current user will not receive push notifications during the specified period of time (from START_TS to END_TS).
[SBDMain setSnoozePeriodEnable:YES startTimestamp:START_TS endTimestamp:END_TS completionHandler:^(SBDError * _Nullable error) {
    if (error != nil) { // Error.
        return;
    }
}];
Light Color Skin
Copy
// The current user will not receive push notifications during the specified period of time (from START_TS to END_TS).
SBDMain.setSnoozePeriodEnable(true, startTimestamp: START_TS, endTimestamp: END_TS, completionHandler: { (error) in
    if error != nil {   // Error.
        return
    }
})

Push notification message templates

Push notification message templates are forms about how the content of a notification message is displayed when the message arrives to a user's device. You can choose between the default template and alternative template, both of which are customizable.

Message templates

Text messageFile message

Default template

{sender_name}: {message} (ex. John: Hello!)

{filename} (ex. squirrel.jpg)

Alternative template

New message arrived

New file arrived

The {sender_name}, {message}, and {filename} above represent the corresponding string values. Use these fields to customize message templates from your dashboard's Settings > Application > Notifications tab. The option is under the Push Notification Message Templates part.

To determine in which template a message is displayed, use the setPushTemplateWithName:completionHandler: method. You can specify the name of a template with SBD_PUSH_TEMPLATE_DEFAULT or SBD_PUSH_TEMPLATE_ALTERNATIVE.

Objective-C
Swift
Light Color Skin
Copy
[SBDMain setPushTemplateWithName:SBD_PUSH_TEMPLATE_ALTERNATIVE completionHandler:^(SBDError * _Nullable error) {
    if (error != nil) { // Error.
        return;
    }

    // Push template successfully set to SBD_PUSH_TEMPLATE_ALTERNATIVE.
}];
Light Color Skin
Copy
SBDMain.setPushTemplateWithName(SBD_PUSH_TEMPLATE_ALTERNATIVE) { (error) in
    if error != nil { // Error.
        return
    }

    // Push template successfully set to SBD_PUSH_TEMPLATE_ALTERNATIVE.
}

Note: By default, a message template is SBD_PUSH_TEMPLATE_DEFAULT.

You can check your current setting with getPushTemplateWithCompletionHandler: like the following.

Objective-C
Swift
Light Color Skin
Copy
[SBDMain getPushTemplateWithCompletionHandler:^(NSString * _Nullable name, SBDError * _Nullable error) {
    if (error != nil) { // Error.
        return;
    }

    if ([name isEqualToString:SBD_PUSH_TEMPLATE_DEFAULT]) {
        // Currently configured to use the default template.
    }
    else if ([name isEqualToString:SBD_PUSH_TEMPLATE_ALTERNATIVE]) {
        // Currently configured to use the alternative template.
    }
}];
Light Color Skin
Copy
SBDMain.getPushTemplate { (name, error) in
    if error != nil { // Error.
        return
    }

    if name == SBD_PUSH_TEMPLATE_DEFAULT {
        // Currently configured to use the default template.
    }
    else if name == SBD_PUSH_TEMPLATE_ALTERNATIVE {
        // Currently configured to use the alternative template.
    }
}