Agora Chat supports the integration of Apple Push Notification service (APNs). This enables iOS developers to use an offline push notification service. The service features low latency, high delivery, high concurrency, and no violation of the users' personal data.
The following figure shows the basic workflow of Agora Chat:
Assume that User A sends a message to User B, but User B goes offline before receiving it. The Agora Chat server pushes a notification to the device of User B via APN and temporarily stores this message. Once User B comes back online, the Agora Chat SDK pulls the message from the server and pushes the message to User B using persistent connections.
Before proceeding, ensure that you meet the following requirements:
Follow these steps to enable the APNs service:
Request a Certificate Signing Request (CSR) file.
CertificateSigningRequest.certSigningRequest
in the specified path.com.YourCompany.YourProjectName
format.Create a push certificate for both the development environment and the production environment in turn.
Generate the push certificate.
.p12
file, and set the certificate key.Generate a Provisioning Profile file.
Follow the steps to upload the certificates to Agora Console:
Log in to Agora Console, and click Project Management in the left navigation bar.
On the Project Management page, locate the project that has Chat enable and click Config.
On the project edit page, click Config next to Chat.
On the project config page, select Features > Push Certificate and click Add Push Certificate.
In the pop-up window, select the APPLE tab, and configure the following fields:
Certificate Type: Select the file type specified when the certificate was exported. In this case, select p12.
Certificate Name: Fill in the name specified when the certificate was exported.
Push Key: Fill in the secret specified when the certificate was exported.
Upload Certificate: Upload the certificate exported.
Integration Environment: Select Development or Production Environment. Upload the p12
file for the development and production environments in turn.
Bind ID: Fill in the bundle ID specified when the App ID was created.
Click Save to add the push certificate.
Open Xcode, and select TARGETS > Capability > Push Notifications to enable push notifications.
Pass the certificate name to the SDK.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Register for notifications
[application registerForRemoteNotifications];
// Initialize Options and set AppKey
AgoraChatOptions *options = [AgoraChatOptions optionsWithAppkey:@"XXXX#XXXX"];
// Fill in the name specified when uploading the certificate
options.apnsCertName = @"PushCertName";
[AgoraChatClient.sharedClient initializeSDKWithOptions:options];
return YES;
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
[AgoraChatClient.sharedClient registerForRemoteNotificationsWithDeviceToken:deviceToken completion:^(AgoraChatError *aError) {
if (aError) {
NSLog(@"bind deviceToken error: %@", aError.errorDescription);
}
}];
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(@"Register Remote Notifications Failed");
}
To optimize user experience when dealing with an influx of push notifications, Agora Chat provides fine-grained options for the push notification and do-not-disturb (DND) modes at both the app and conversation levels, as shown in the following table:
|
|
|
|
---|---|---|---|
|
All : Receives push notifications for all offline messages. |
|
|
MentionOnly : Only receives push notifications for mentioned messages. |
|
|
|
None : Do not receive push notifications for offline messages. |
|
|
|
|
silentModeDuration : Do not receive push notifications for the specified duration. |
|
|
silentModeStartTime & silentModeEndTime : Do not receive push notifications in the specified time frame. |
|
|
Push notification mode
The setting of the push notification mode at the conversation level takes precedence over that at the app level, and those conversations that do not have specific settings for the push notification mode inherit the app setting by default.
For example, assume that the push notification mode of the app is set to MentionOnly
, while that of the specified conversation is set to All
. You receive all the push notifications from this conversation, while you only receive the push notifications for mentioned messages from all the other conversations.
Do-not-disturb mode
For both the app and all the conversations in the app, the setting of the DND mode takes precedence over the setting of the push notification mode.
For example, assume that a DND time period is specified at the app level and the push notification mode of the specified conversation is set to All
. The DND mode takes effect regardless of the setting of the push notification mode, that is, you do not receive any push notifications during the specified DND time period.
Alternatively, assume that a DND time period is specified for a conversation, while the app does not have any DND settings and its push notification mode is set to All
. You do not receive any push notifications from this conversation during the specified DND time period, while the push of all the other conversations remains the same.
You can call setSilentModeForAll
to set the push notifications at the app level and set the push notification mode and DND mode by specifying the AgoraChatSilentModeParam
field, as shown in the following code sample:
// Sets the push notification mode to `MentionOnly` for an app.
AgoraChatSilentModeParam *param = [[AgoraChatSilentModeParam alloc]initWithParamType:AgoraChatSilentModeParamTypeRemindType];
param.remindType = AgoraChatPushRemindTypeMentionOnly;
// Sets the push notifications at the app level.
[[AgoraChatClient sharedClient].pushManager setSilentModeForAll:param completion:^(AgoraChatSilentModeResult *aResult, AgoraChatError *aError) {
if (aError) {
NSLog(@"setSilentModeForAll error---%@",aError.errorDescription);
}
}];
// Sets the DND duration to 15 minutes.
AgoraChatSilentModeParam *param = [[AgoraChatSilentModeParam alloc]initWithParamType:AgoraChatSilentModeParamTypeDuration];
param.silentModeDuration = 15;
// Sets the DND time frame from 8:30 to 15:00.
AgoraChatSilentModeParam *param = [[AgoraChatSilentModeParam alloc]initWithParamType:AgoraChatSilentModeParamTypeDuration];
param.silentModeStartTime = [[AgoraChatSilentModeTime alloc]initWithHours:8 minutes:30];
param.silentModeEndTime = [[AgoraChatSilentModeTime alloc]initWithHours:15 minutes:0];
You can call getSilentModeForAllWithCompletion
to retrieve the push notification settings at the app level, as shown in the following code sample:
[[AgoraChatClient sharedClient].pushManager getSilentModeForAllWithCompletion:^(AgoraChatSilentModeResult *aResult, AgoraChatError *aError) {
if (!aError) {
// Retrieves the setting of the push notification mode at the app level.
AgoraChatPushRemindType remindType = aResult.remindType;
// Retrieves the Unix timestamp when the DND duration of an app expires.
NSTimeInterval ex = aResult.expireTimestamp;
// Retrieves the start time specified in the DND time frame at the app level.
AgoraChatSilentModeTime *startTime = aResult.silentModeStartTime;
// Retrieves the end time specified in the DND time frame at the app level.
AgoraChatSilentModeTime *endTime = aResult.silentModeEndTime;
}else{
NSLog(@"getSilentModeForAll error---%@",aError.errorDescription);
}
}];
You can call setSilentModeForConversation
to set the push notifications for the conversation specified by the conversationId
and AgoraChatConversationType
fields, as shown in the following code sample:
// Sets the push notification mode to `MentionOnly` for a conversation.
AgoraChatSilentModeParam *param = [[AgoraChatSilentModeParam alloc]initWithParamType:AgoraChatSilentModeParamTypeRemindType];
param.remindType = AgoraChatPushRemindTypeMentionOnly;
// Sets the DND duration to 15 minutes.
AgoraChatSilentModeParam *param = [[AgoraChatSilentModeParam alloc]initWithParamType:AgoraChatSilentModeParamTypeDuration];
param.silentModeDuration = 15;
// Sets the push notifications at the conversation level.
AgoraChatConversationType conversationType = AgoraChatConversationTypeGroupChat;
[[AgoraChatClient sharedClient].pushManager setSilentModeForConversation:@"conversationId" conversationType:conversationType params:param completion:^(AgoraChatSilentModeResult *aResult, AgoraChatError *aError) {
if (aError) {
NSLog(@"setSilentModeForConversation error---%@",aError.errorDescription);
}
}];
You can call getSilentModeForConversation
to retrieve the push notification settings of the conversation specified by the conversationId
and AgoraChatConversationType
fields, as shown in the following code sample:
[[AgoraChatClient sharedClient].pushManager getSilentModeForConversation:@"conversationId" conversationType:AgoraChatConversationTypeChat completion:^(AgoraChatSilentModeResult * _Nullable aResult, AgoraChatError * _Nullable aError) {
}];
You can call getSilentModeForConversations
to retrieve the push notification settings of multiple conversations, as shown in the following code sample:
NSArray *conversations = @[conversation1,conversation2];
[[AgoraChatClient sharedClient].pushManager getSilentModeForConversations:conversationArray completion:^(NSDictionary<NSString*,AgoraChatSilentModeResult*>*aResult, AgoraChatError *aError) {
if (aError) {
NSLog(@"getSilentModeForConversations error---%@",aError.errorDescription);
}
}];
You can call clearRemindTypeForConversation
to clear the push notification mode of the specified conversation. Once the specific setting of a conversation is cleared, this conversation inherits the app setting by default.
The following code sample shows how to clear the push notification mode of a conversation:
[[AgoraChatClient sharedClient].pushManager clearRemindTypeForConversation:@"" conversationType:conversationType completion:^(AgoraChatSilentModeResult *aResult, AgoraChatError *aError) {
if (aError) {
NSLog(@"clearRemindTypeForConversation error---%@",aError.errorDescription);
}
}];
You can call updatePushDisplayName
to set the nickname displayed in your push notifications, as shown in the following code sample:
[AgoraChatClient.sharedClient.pushManager updatePushDisplayName:@"displayName" completion:^(NSString * aDisplayName, AgoraChatError * aError) {
if (aError)
{
NSLog(@"update push display name error: %@", aError.errorDescription);
}
}];
You can also call updatePushDisplayStyle
to set the display style of push notifications, as shown in the following code sample:
// `AgoraPushDisplayStyleSimpleBanner` indicates that only "You have a new message" displays.
// To display the message content, set `DisplayStyle` to `AgoraPushDisplayStyleMessageSummary`.
[AgoraChatClient.sharedClient.pushManager updatePushDisplayStyle:AgoraPushDisplayStyleSimpleBanner completion:^(AgoraChatError * aError)
{
if(aError)
{
NSLog(@"update display style error --- %@", aError.errorDescription);
}
}];
You can call getPushNotificationOptionsFromServerWithCompletion
to retrieve the display attributes in push notifications, as shown in the following code sample:
[[AgoraChatClient sharedClient] getPushNotificationOptionsFromServerWithCompletion:^(AgoraChatPushOptions *aOptions, AgoraChatError *aError) {
if (!aError) {
// Retrieves the nickname displayed in push notifications.
NSString *displayName = aOptions.displayName;
// Retrieves the display style of push notifications.
AgoraChatPushDisplayStyle dispalyStyle = aOptions.displayStyle;
}
}];
If a user enables the automatic translation feature and sends a message, the SDK sends both the original message and the translated message.
Push notifications work in tandem with the translation feature. As a receiver, you can set the preferred language of push notifications that you are willing to receive when you are offline. If the language of the translated message meets your setting, the translated message displays in push notifications; otherwise, the original message displays instead.
The following code sample shows how to set and retrieve the preferred language of push notifications
// Sets the preferred language of push notifications.
[[AgoraChatClient sharedClient].pushManager setPreferredNotificationLanguage:@"EU" completion:^(AgoraChatError *aError) {
if (aError) {
NSLog(@"setPushPerformLanguageCompletion error---%@",aError.errorDescription);
}
}];
// Retrieves the preferred language of push notifications.
[[AgoraChatClient sharedClient].pushManager getPreferredNotificationLanguageCompletion:^(NSString *aLaguangeCode, AgoraChatError *aError) {
if (!aError) {
NSLog(@"getPushPerformLanguage---%@",aLaguangeCode);
}
}];
Agora Chat allows users to use ready-made templates for push notifications.
You can create and provide push templates for users by referring to the following steps:
Log in to Agora Console, and click Project Management in the left navigation bar.
On the Project Management page, locate the project that has Chat enable and click Config.
On the project edit page, click Config next to Chat.
On the project config page, select Features > Push Template and click Add Push Template, and configure the fields in the pop-up window, as shown in the following figure:
Once the template creation is complete in Agora Console, users can choose this push template as their default layout when sending a message, as shown in the following code sample:
// This code sample takes a TXT message as an example. You can use the same approach to set IMAGE messages and FILE messages.
AgoraChatTextMessageBody *body = [[AgoraChatTextMessageBody alloc]initWithText:@"test"];
AgoraChatMessage *message = [[AgoraChatMessage alloc]initWithConversationID:@"conversationId" from:@"currentUsername" to:@"conversationId" body:body ext:nil];
// Sets the push template created in Agora Console as their default layout.
NSDictionary *pushObject = @{
@"name":@"templateName",// Sets the template name.
@"title_args":@[@"titleValue1"],// Sets the template title by specifying the variable.
@"content_args":@[@"contentValue1"]// Sets the template content by specifying the variable.
};
message.ext = @{
@"em_push_template":pushObject,
};
message.chatType = AgoraChatTypeChat;
[[AgoraChatClient sharedClient].chatManager sendMessage:message progress:nil completion:nil];
This section includes more versatile push notification features that you can use to implement additional functions if needed.
If the ready-made templates do not meet your requirements, Agora Chat also enables you to customize your push notifications.
The following code sample shows how to add an extension field in push notifications:
AgoraChatTextMessageBody *body = [[AgoraChatTextMessageBody alloc] initWithText:@"test"];
AgoraChatMessage *message = [[AgoraChatMessage alloc] initWithConversationID:conversationId from:currentUsername to:conversationId body:body ext:nil];
message.ext = @{@"em_apns_ext":@{@"extern":@"custom string"}};
message.chatType = AgoraChatTypeChat;
[AgoraChatClient.sharedClient.chatManager sendMessage:message progress:nil completion:nil];
Parameter | Description |
---|---|
body |
The displayed content of the message. |
ConversationID |
The ID of the session to which the message belongs. |
from |
The username of the sender. |
to |
The username of the receiver. |
em_apns_ext |
The message extension field. |
extern |
The message extension content. |
An example is as follows:
{
"apns": {
"alert": {
"body": "test"
},
"badge": 1,
"sound": "default"
},
"e": "custom string",
"f": "6001",
"t": "6006",
"m": "373360335316321408"
}
Parameter | Description |
---|---|
body |
The displayed content of the message. |
badge |
The number of push notifications. |
sound |
The sound of push notifications. |
f |
The username of the sender. |
t |
The username of the receiver. |
e |
The custom message. |
m |
The ID of the message. |
The following code sample shows how to customize the display style in push notifications:
AgoraChatTextMessageBody *body = [[AgoraChatTextMessageBody alloc] initWithText:@"test"];
AgoraChatMessage *message = [[AgoraChatMessage alloc] initWithConversationID:conversationId from:currentUsername to:conversationId body:body ext:nil];
message.ext = @{@"em_apns_ext":@{
@"em_alert_title": @"customTitle",
@"em_alert_subTitle": @"customSubTitle",
@"em_alert_body": @"customBody"
}};
message.chatType = AgoraChatTypeChat;
[AgoraChatClient.sharedClient.chatManager sendMessage:message progress:nil completion:nil];
Parameter | Description |
---|---|
body |
The displayed content of the message. |
ConversationID |
The ID of the session to which the message belongs. |
from |
The username of the sender. |
to |
The username of the receiver. |
em_apns_ext |
The extension field. |
em_alert_title |
The title of push notifications. |
em_alert_subTitle |
The subtitle of push notifications. |
em_alert_body |
The content of push notifications. |
An example is as follows:
{
"aps":{
"alert":{
"body":"custom push content"
},
"badge":1,
"sound":"default"
},
"f":"6001",
"t":"6006",
"m":"373360335316321408",
}
Parameter | Description |
---|---|
body |
The displayed content of the message. |
badge |
The number of push notifications. |
sound |
The sound of push notifications. |
f |
The username of the sender. |
t |
The username of the receiver. |
m |
The ID of the message. The unique identifier of the message. |
To use a custom sound for push notifications, you need to add the audio file to the app and configure the filename for the push. For details, see Apple Official Documentation.
The following sample code customizes the sound of the push notification:
AgoraChatTextMessageBody *body = [[AgoraChatTextMessageBody alloc] initWithText:@"test"];
AgoraChatMessage *message = [[AgoraChatMessage alloc] initWithConversationID:conversationId from:currentUsername to:conversationId body:body ext:nil];
message.ext = @{@"em_apns_ext":@{@"em_push_sound":@"custom.caf"}};
message.chatType = AgoraChatTypeChat;
[AgoraChatClient.sharedClient.chatManager sendMessage:message progress:nil completion:nil];
Parameter | Description |
---|---|
body |
The displayed content of the message. |
ConversationID |
The ID of the session to which the message belongs. |
from |
The username of the sender. |
to |
The username of the receiver. |
em_apns_ext |
The extension field. |
em_push_sound |
The custom sound. |
custom.caf |
The filename of the sound. |
An example is as follows:
{
"aps":{
"alert":{
"body":"You have a new message"
},
"badge":1,
"sound":"custom.caf"
},
"f":"6001",
"t":"6006",
"m":"373360335316321408"
}
Parameter | Description |
---|---|
body |
The displayed content of the message. |
badge |
The number of push notifications. |
sound |
The sound of push notifications. |
f |
The username of the sender. |
t |
The username of the receiver. |
m |
The ID of the message. The unique identifier of the message. |
Once you force a push notification to a user, the user receives the message regardless of the do-not-disturb settings.
The following sample code forces a push notification:
AgoraChatTextMessageBody *body = [[AgoraChatTextMessageBody alloc] initWithText:@"test"];
AgoraChatMessage *message = [[AgoraChatMessage alloc] initWithConversationID:conversationId from:currentUsername to:conversationId body:body ext:nil];
message.ext = @{@"em_force_notification":@YES};
message.chatType = AgoraChatTypeChat;
[AgoraChatClient.sharedClient.chatManager sendMessage:message progress:nil completion:nil];
Parameter | Description |
---|---|
body |
The displayed content of the message. |
ConversationID |
The ID of the session to which the message belongs. |
from |
The username of the sender. |
to |
The username of the receiver. |
em_force_notification |
Whether to force a push notification: |
If the receiver uses a device running iOS 10.0 or later, you can refer to the following sample code to enable theUNNotificationServiceExtension
extension.
AgoraChatTextMessageBody *body = [[AgoraChatTextMessageBody alloc] initWithText:@"test"];
AgoraChatMessage *message = [[AgoraChatMessage alloc] initWithConversationID:conversationId from:currentUsername to:conversationId body:body ext:nil];
message.ext = @{@"em_apns_ext":@{@"em_push_mutable_content":@YES}};
message.chatType = AgoraChatTypeChat;
[AgoraChatClient.sharedClient.chatManager sendMessage:message progress:nil completion:nil];
Parameter | Description |
---|---|
body |
The displayed content of the message. |
ConversationID |
The ID of the session to which the message belongs. |
from |
The username of the sender. |
to |
The username of the receiver. |
em_apns_ext |
The extension field. |
em_push_mutable_content |
Whether to use em_apns_ext . |
An example is as follows:
{
"aps":{
"alert":{
"body":"test"
},
"badge":1,
"sound":"default",
"mutable-content":1
},
"f":"6001",
"t":"6006",
"m":"373360335316321408"
}
Parameter | Description |
---|---|
body |
The displayed content of the message. |
badge |
The number of push notifications. |
sound |
The sound of push notifications. |
mutable-content |
Set the value to 1 to enable UNNotificationServiceExtension . |
f |
The username of the sender. |
t |
The username of the receiver. |
m |
The ID of the message. |