====== iOS 推送设置 ====== 更新时间:2022-07-28 APNs 是苹果官方提供的推送解决方案,主要用于在 app 处于不活跃状态时向设备发送实时通知。使用环信即时通讯 IM SDK 时,当消息接收方不在线,环信即时通讯 IM 的服务器会通过苹果的 APNs 服务向接收方设备发消息推送,该服务器会暂时保存这些消息,等用户再次上线时通过环信即时通讯 IM 的长连接投递。同时开发者可根据需要设置推送的显示样式,免打扰时间段等。 比如:当你的 app 处于不活跃状态时,有用户向你发送了消息,此时你的手机的通知中心会弹出消息相关的通知,当你再次打开 app 并登录成功,环信即时通讯 IM SDK 会主动拉取你不在线时的消息。 你不需要单独处理和消息相关的 APNs,通过 APNs 收到的只是消息通知,等用户账号登录成功后才会把消息从服务器拉过来。这里角标表示的是离线消息数,并不是实际的未读消息数。 ===== 技术原理 ===== {{https://docs-im.easemob.com/_media/im/ios/apns/image007.png| 推送}} ===== 前提条件 ===== 1. 使用消息推送前,需要在你的设备[[ccim:ios:push#开启推送权限并上传推送证书|开启推送权限,并将推送证书上传到环信即时通讯 IM 管理后台]]。
2. 若使用 3.9.2 及以上版本提供的推送高级功能,包括设置推送通知模式、免打扰模式和自定义推送模板,你需要在环信即时通讯云控制后台中激活推送高级功能。
{{:ccim:web:enable_push_new.png|}} ==== 开启推送权限并上传推送证书 ==== === 1. 生成 CSR 文件 === 生成 Certificate Signing Request(CSR): {{:ccim:ios:push_ios_create_csr01.jpeg?1500|}} 填写你的邮箱(这个邮箱是申请 App ID 的付费帐号)和常用名称(一般默认是计算机名,不用更改),并选择保存到硬盘: {{:ccim:ios:push_ios_create_csr02.jpeg?1500|}} 点击继续: {{:ccim:ios:push_ios_create_csr03.jpeg?1500|}} 在本地生成了名为 ''%%EMImDemoAPS.certSigningRequest%%'' 的 CSR 文件 。 === 2. 创建 App ID === 生成 App ID ,如果已经有 App ID 可以跳至第3步。 {{:ccim:ios:push_ios_create_app01.jpeg?1500|}} 选择 App ID,点击 ''%%Continue%%''; {{:ccim:ios:push_ios_create_app02.jpeg?1500|}} 选择 App, 点击 ''%%Continue%%''; {{:ccim:ios:push_ios_create_app03.jpeg?1500|}} 输入你的 App ID 描述信息,可以输入工程名;Bunble ID(在工程的 General 信息中),一般格式为 com.youcompany.youprojname。 {{:ccim:ios:push_ios_create_app04.jpeg?1500|}} 选择需要支持 ''%%Push Notification%%'',点击 ''%%Continue%%''; {{:ccim:ios:push_ios_create_app05.jpeg?1500|}} 确定信息无误,点击 ''%%Register%%''; {{:ccim:ios:push_ios_create_app06.jpeg?1500|}} === 3. 创建 app 的 APS 证书 === 回到 App IDs 选择你需要推送的 app。 {{:ccim:ios:push_ios_create_aps01.jpeg?1500|}} 找到 ''%%Push Notifications%%'', 点击 ''%%Configure%%''。 {{:ccim:ios:push_ios_create_aps02.jpeg?1500|}} 如果是开发模式,点击 ''%%Development SSL Certificate%%'' 下的 ''%%Create Certificate%%''。如果是生产模式,点击 ''%%Production SSL Certificate%%'' 下的 ''%%Create Certificate%%'' 。 {{:ccim:ios:push_ios_create_aps03.jpeg?1500|}} ''%%Platform%%'' 选择 ''%%iOS%%'' , ''%%Choose File%%'' 选择第一步中创建的 ''%%CSR%%'' 文件,点击 ''%%Continue%%''。 {{:ccim:ios:push_ios_create_aps04.jpeg?1500|}} aps 文件创建成功了,点击 ''%%Download%%'' 下载到本地。(文件名:开发版本为 aps_development.cer,发布版本为 aps.cer): {{:ccim:ios:push_ios_create_aps05.jpeg?1500|}} === 4. 生成 Push 证书 === 导入证书 双击上一节下载的文件(''%%aps_development.cer%%'' 和 ''%%aps.cer%%'')将其安装到电脑,在“钥匙串访问”中,可以看到已经导入的证书。 {{:ccim:ios:push_ios_create_push01.jpeg?1500|}} 右键选择导出为 p12 文件, (例:存储为 ''%%EMImDemoAPS.p12%%''): {{:ccim:ios:push_ios_create_push02.jpeg?1500|}} === 5. 生成 Provisioning Profile 文件(PP 文件) === {{:ccim:ios:push_ios_create_pp01.jpeg?1500|}} 选择 ''%%iOS App Development%%''(这里演示开发版描述文件的创建, 发布版本的创建流程一样,如果发布版本,请选择 App Store),点击 Continue。 {{:ccim:ios:push_ios_create_pp02.jpeg?1500|}} App ID 选择需要创建 PP 文件的 App ID, 点击 ''%%Continue%%''。 {{:ccim:ios:push_ios_create_pp03.jpeg?1500|}} {{:ccim:ios:push_ios_create_pp04.jpeg?1500|}} 选择需要加入开发的设备,只有加入了的设备才能进行真机调试,创建发布版本时没有这个步骤,点击 ''%%Continue%%''。 {{:ccim:ios:push_ios_create_pp05.jpeg?1500|}} 输入 PP 文件的名称,点击 ''%%Generate%%''。 {{:ccim:ios:push_ios_create_pp06.jpeg?1500|}} PP 文件生成完成, 点击 ''%%Download%%''。 {{:ccim:ios:push_ios_create_pp07.jpeg?1500|}} === 6. 上传到环信即时通讯 IM 管理后台 === {{:ccim:ios:push_ios_upload_certification.png|}} ===== 在客户端实现推送 ===== ==== 1. 在 app 中开启推送权限 ==== 需要在 xcode 中为 app 开启推送权限。 Targets -> Capability -> Push Notifications {{:ccim:ios:enable_push_notifications.jpeg?1500|}} ==== 2. 将证书名称传递给 SDK ==== - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 注册推送。 [application registerForRemoteNotifications]; // 初始化 `Options`,设置 App Key。 EMOptions *options = [EMOptions optionsWithAppkey:@"easemob-demo#easeim"]; // 填写上传证书时设置的名称。 options.apnsCertName = @"PushCertName"; [EMClient.sharedClient initializeSDKWithOptions:options]; return YES; } ==== 3. 获取并将 device token 传递给 SDK ==== DeviceToken 注册后,iOS 系统会通过以下方式将 DeviceToken 回调给你,你需要把 DeviceToken 传给 SDK。 - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [EMClient.sharedClient registerForRemoteNotificationsWithDeviceToken:deviceToken completion:^(EMError *aError) { if (aError) { NSLog(@"bind deviceToken error: %@", aError.errorDescription); } }]; } - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { NSLog(@"Register Remote Notifications Failed"); } ==== 4. 设置离线推送 ==== 环信 IM 3.9.2 及以上版本对离线消息推送进行了优化。你可以对 app 以及各类型的会话开启和关闭离线推送功能,关闭时可设置关闭时长。 环信 IM 支持你对离线推送功能进行如下配置: * 设置推送通知,包含设置推送通知方式和免打扰模式。 * 配置推送翻译和推送模板。 === 4.1 设置推送通知 === 为优化用户在处理大量推送通知时的体验,环信 IM 在 app 和会话层面提供了推送通知和免打扰(DND)模式的细粒度选项,如下表所示:
模式 选项 App 会话
推送通知方式 All:接收所有离线消息的推送通知。
MentionOnly:仅接收提及消息的推送通知。
NONE:不接收离线消息的推送通知。
免打扰模式 silentModeDuration:在指定时长内不接收推送通知。
silentModeStartTime & silentModeEndTime:在指定的时间范围内不接收推送通知。
**推送通知方式** 会话级别的推送通知方式设置优先于 app 级别的设置,未设置推送通知方式的会话默认采用 app 的设置。 例如,假设 app 的推送方式设置为 ''%%MentionOnly%%'',而指定会话的推送方式设置为 ''%%All%%''。你会收到来自该会话的所有推送通知,而对于其他会话来说,你只会收到提及你的消息的推送通知。 **免打扰模式** - 你可以在 app 级别指定 DND 时长和 DND 时间范围。环信 IM 在这两个时间段内不发送离线推送通知。 - 会话仅支持 DND 时长设置;DND 时间范围的设置不生效。 对于 app 和 app 中的所有会话,DND 模式的设置优先于推送通知方式的设置。 例如,假设在 app 级别指定了免打扰时间段,并将指定会话的推送通知方式设置为 ''%%All%%''。免打扰模式与推送通知方式的设置无关,即在指定的免打扰时间段内,你不会收到任何推送通知。 或者,假设为会话指定了免打扰时间段,而 app 没有任何免打扰设置,并且其推送通知方式设置为 ''%%All%%''。在指定的免打扰时间段内,你不会收到来自该会话的任何推送通知,而所有其他会话的推送保持不变。 == 4.1.1 设置 app 的推送通知 == 你可以调用 ''%%setSilentModeForAll%%'' 设置 app 级别的推送通知,并通过指定 ''%%EMSilentModeParam%%'' 字段设置推送通知方式和免打扰模式,如下代码示例所示: //设置推送通知方式为 `MentionOnly`。 EMSilentModeParam *param = [[EMSilentModeParam alloc]initWithParamType:EMSilentModeParamTypeRemindType]; param.remindType = EMPushRemindTypeMentionOnly; //设置 app 的离线推送免打扰模式。 [[EMClient sharedClient].pushManager setSilentModeForAll:param completion:^(EMSilentModeResult *aResult, EMError *aError) { if (aError) { NSLog(@"setSilentModeForAll error---%@",aError.errorDescription); } }]; //设置离线推送免打扰时长为 15 分钟。 EMSilentModeParam *param = [[EMSilentModeParam alloc]initWithParamType:EMSilentModeParamTypeDuartion]; param.silentModeDuration = 15; //设置离线推送的免打扰时间段为 8:30 到 15:00。 EMSilentModeParam *param = [[EMSilentModeParam alloc]initWithParamType:EMSilentModeParamTypeInterval]; param.silentModeStartTime = [[EMSilentModeTime alloc]initWithHours:8 minutes:30]; param.silentModeEndTime = [[EMSilentModeTime alloc]initWithHours:15 minutes:0]; == 4.1.2 获取 app 的推送通知设置 == 你可以调用 ''%%getSilentModeForAll%%'' 获取 app 级别的推送通知设置,如以下代码示例所示: [[EMClient sharedClient].pushManager getSilentModeForAllWithCompletion:^(EMSilentModeResult *aResult, EMError *aError) { if (!aError) { //获取 app 的推送通知方式。 EMPushRemindType remindType = aResult.remindType; //获取 app 的离线推送免打扰过期 Unix 时间戳。 NSTimeInterval ex = aResult.expireTimestamp; //获取 app 的离线推送免打扰时段的开始时间。 EMSilentModeTime *startTime = aResult.silentModeStartTime; EMSilentModeTime *endTime = aResult.silentModeEndTime; }else{ NSLog(@"getSilentModeForAll error---%@",aError.errorDescription); } }]; == 4.1.3 设置单个会话的推送通知 == 你可以调用 ''%%setSilentModeForConversation%%'' 设置指定会话的推送通知,并通过指定 ''%%EMSilentModeParam%%'' 字段设置推送通知方式和免打扰模式,如以下代码示例所示: //设置推送通知方式为 `MentionOnly`。 EMSilentModeParam *param = [[EMSilentModeParam alloc]initWithParamType:EMSilentModeParamTypeRemindType]; param.remindType = EMPushRemindTypeMentionOnly; //设置离线推送免打扰时长为 15 分钟。 EMSilentModeParam *param = [[EMSilentModeParam alloc]initWithParamType:EMSilentModeParamTypeDuartion]; param.silentModeDuration = 15; EMConversationType conversationType = EMConversationTypeGroupChat; [[EMClient sharedClient].pushManager setSilentModeForConversation:@"conversationId" conversationType:conversationType params:param completion:^(EMSilentModeResult *aResult, EMError *aError) { if (aError) { NSLog(@"setSilentModeForConversation error---%@",aError.errorDescription); } }]; == 4.1.4 获取单个会话的推送通知设置 == 你可以调用 ''%%getSilentModeForAllWithCompletion%%'' 获取指定会话的推送通知设置,如以下代码示例所示: [[EMClient sharedClient].pushManager getSilentModeForAllWithCompletion:^(EMSilentModeResult *aResult, EMError *aError) { if (!aError) { //获取会话的推送通知方式。 if(aResult.isSetConversationRemindType){ EMPushRemindType remindType = aResult.remindType; } //获取会话的离线推送免打扰过期 Unix 时间戳。 NSTimeInterval ex = aResult.expireTimestamp; //获取会话的离线推送免打扰时段的开始时间。 EMSilentModeTime *startTime = aResult.silentModeStartTime; EMSilentModeTime *endTime = aResult.silentModeEndTime; }else{ NSLog(@"getSilentModeForAll error---%@",aError.errorDescription); }s }]; == 4.1.5 获取多个会话的推送通知设置 == - 你可以在每次调用中最多获取 20 个会话的设置。 - 如果会话继承了 app 设置或其推送通知设置已过期,则返回的字典不包含此会话。 你可以调用 ''%%getSilentModeForConversations%%'' 获取多个会话的推送通知设置,如以下代码示例所示: NSArray *conversations = @[conversation1,conversation2]; [[EMClient sharedClient].pushManager getSilentModeForConversations:conversationArray completion:^(NSDictionary*aResult, EMError *aError) { if (aError) { NSLog(@"getSilentModeForConversations error---%@",aError.errorDescription); } }]; == 4.1.6 清除单个会话的推送通知方式的设置 == 你可以调用 ''%%clearRemindTypeForConversation:%%'' 清除指定会话的推送通知方式的设置。清除后,默认情况下,此会话会继承 app 的设置。 以下代码示例显示了如何清除会话的推送通知方式的设置: //清除指定会话的推送通知方式的设置。清除后,该会话会采取 app 的设置。 [[EMClient sharedClient].pushManager clearRemindTypeForConversation:@"" conversationType:conversationType completion:^(EMSilentModeResult *aResult, EMError *aError) { if (aError) { NSLog(@"clearRemindTypeForConversation error---%@",aError.errorDescription); } }]; === 4.2 设置显示属性 === == 4.2.1 设置推送通知的显示属性 == 你可以调用 ''%%updatePushDisplayName%%'' 设置推送通知中显示的昵称,如以下代码示例所示: [EMClient.sharedClient.pushManager updatePushDisplayName:@"displayName" completion:^(NSString * aDisplayName, EMError * aError) { if (aError) { NSLog(@"update push display name error: %@", aError.errorDescription); } }]; 你也可以调用 ''%%updatePushDisplayStyle%%'' 设置推送通知的显示样式,如下代码示例所示: [EMClient.sharedClient.pushManager updatePushDisplayStyle:EMPushDisplayStyleSimpleBanner completion:^(EMError * aError) { if(aError) { NSLog(@"update display style error --- %@", aError.errorDescription); } }]; ''%%DisplayStyle%%'' 是枚举类型。 ^参数 ^描述 ^ |''%%EMPushDisplayStyleSimpleBanner%%'' |显示“你有一条新消息”。 | |''%%EMPushDisplayStyleMessageSummary%%'' |显示消息内容。 | == 4.2.2 获取推送通知的显示属性 == 你可以调用 ''%%getPushNotificationOptionsFromServerWithCompletion%%'' 获取推送通知中的显示属性,如以下代码示例所示: [EMClient.sharedClient.pushManager getPushNotificationOptionsFromServerWithCompletion:^(EMPushOptions * aOptions, EMError * aError) { if (aError) { NSLog(@"get push options error --- %@", aError.errorDescription); } }]; ''%%EMPushOptions%%'' 推送配置对象。 ^属性名 ^描述 ^ |''%%displayName%%'' |对方收到推送时发送方展示的名称。 | |''%%displayStyle%%'' |推送显示类型。 | ==== 4.3 设置推送翻译 ==== 如果用户启用 [[https://docs-im.easemob.com/ccim/ios/translation#%E8%AE%BE%E7%BD%AE%E8%87%AA%E5%8A%A8%E7%BF%BB%E8%AF%91|自动翻译]]功能并发送消息,SDK 会同时发送原始消息和翻译后的消息。 推送通知与翻译功能协同工作。作为接收方,你可以设置你在离线时希望接收的推送通知的首选语言。如果翻译消息的语言符合你的设置,则翻译消息显示在推送通知中;否则,将显示原始消息。 以下代码示例显示了如何设置和获取推送通知的首选语言: //设置离线推送的首选语言。 [[EMClient sharedClient].pushManager setPreferredNotificationLanguage:@"EU" completion:^(EMError *aError) { if (aError) { NSLog(@"setPushPerformLanguageCompletion error---%@",aError.errorDescription); } }]; //获取离线推送的首选语言。 [[EMClient sharedClient].pushManager getPreferredNotificationLanguageCompletion:^(NSString *aLaguangeCode, EMError *aError) { if (!aError) { NSLog(@"getPushPerformLanguage---%@",aLaguangeCode); } }]; === 4.4 设置推送模板 === 环信 IM 支持自定义推送通知模板。使用前,你可参考以下步骤在环信即时通讯云管理后台上创建推送模板: - 登录环信 IM Console,进入首页。 - 在 **应用列表** 区域中,点击对应 app 的 **操作** 一栏中的 **查看** 按钮。 - 在环信 IM 配置页面的左侧导航栏,选择 **即时通讯 > 功能配置 > 消息推送 > 模板管理**,进入推送模板管理页面。 {{:ccim:android:push_console_template_mgmt.png|}} - 点击 **添加推送模板**。弹出以下页面,进行参数配置。 {{:ccim:android:push_android_ios_template_add.png|}} 在环信即时通讯云管理后台中完成模板创建后,用户可以在发送消息时选择此推送模板作为默认布局,如下代码示例所示: //下面以文本消息为例,其他类型的消息设置方法相同。 EMTextMessageBody *body = [[EMTextMessageBody alloc]initWithText:@"test"]; EMChatMessage *message = [[EMChatMessage alloc]initWithConversationID:@"conversationId" from:@"currentUsername" to:@"conversationId" body:body ext:nil]; //设置推送模板。设置前需在环信即时通讯云管理后台上创建推送模板。 NSDictionary *pushObject = @{ @"name":@"templateName",//设置推送模板名称。 @"title_args":@[@"titleValue1"],//设置填写模板标题的 value 数组。 @"content_args":@[@"contentValue1"]//设置填写模板内容的 value 数组。 }; message.ext = @{ @"em_push_template":pushObject, }; message.chatType = EMChatTypeChat; [[EMClient sharedClient].chatManager sendMessage:message progress:nil completion:nil]; ==== 5. 解析收到的推送字段 ==== 当设备收到推送并点击时,iOS 会通过 ''%%launchOptions%%'' 将推送中的 JSON 传递给 app,这样就可以根据推送的内容定制 app 的一些行为,比如页面跳转等。 当收到推送通知并点击推送时,app 获取推送内容的方法: - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSDictionary *userInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]; } userInfo: { "aps":{ "alert":{ "body":"你有一条新消息" }, "badge":1, "sound":"default" }, "f":"6001", "t":"6006", "g":"1421300621769", "m":"373360335316321408" } ^参数 ^描述 ^ |''%%body%%'' |显示内容。 | |''%%badge%%'' |角标数。 | |''%%sound%%'' |提示铃声。 | |''%%f%%'' |消息发送方 ID。 | |''%%t%%'' |消息接收方 ID。 | |''%%g%%'' |群组 ID,单聊无该字段。 | |''%%m%%'' |消息 ID。 | ===== 更多功能 ===== ==== 自定义字段 ==== 向推送中添加自定义业务字段满足业务需求,例如,通过这条推送跳转到某个活动页面。 EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"test"]; EMChatMessage *message = [[EMChatMessage alloc] initWithConversationID:conversationId from:currentUsername to:conversationId body:body ext:nil]; message.ext = @{@"em_apns_ext":@{@"extern":@"custom string"}}; message.chatType = EMChatTypeChat; [EMClient.sharedClient.chatManager sendMessage:message progress:nil completion:nil]; ^参数 ^描述 ^ |''%%body%%'' |消息体。 | |''%%ConversationID%%'' |消息属于的会话 ID。 | |''%%from%%'' |消息发送方,一般为当前登录 ID。 | |''%%to%%'' |消息接收方 ID,一般与 ''%%ConversationID%%'' 一致。 | |''%%em_apns_ext%%'' |消息扩展,使用扩展的方式向推送中添加自定义字段,该值为固定值,不可修改。 | |''%%extern%%'' |自定义字段 key,用于设置自定义的内容,该值为固定值,不可修改。 | |''%%custom string%%'' |自定义字段内容。 | **解析的内容** { "apns": { "alert": { "body": "test" }, "badge": 1, "sound": "default" }, "e": "custom string", "f": "6001", "t": "6006", "m": "373360335316321408" } ^参数 ^描述 ^ |''%%body%%'' |显示内容。 | |''%%badge%%'' |角标数。 | |''%%sound%%'' |提示铃声。 | |''%%f%%'' |消息发送方 ID。 | |''%%t%%'' |消息接收方 ID。 | |''%%e%%'' |自定义信息。 | |''%%m%%'' |消息 ID。 | ==== 自定义显示 ==== 自定义显示内容时,你可以随意设置 APNs 通知时显示的内容。 EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"test"]; EMChatMessage *message = [[EMChatMessage 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 = EMChatTypeChat; [EMClient.sharedClient.chatManager sendMessage:message progress:nil completion:nil]; ^参数 ^描述 ^ |''%%body%%'' |消息体。 | |''%%ConversationID%%'' |消息属于的会话 ID。 | |''%%from%%'' |消息发送方,一般为当前登录 ID。 | |''%%to%%'' |消息接收方 ID,一般与 ''%%ConversationID%%'' 一致。 | |''%%em_apns_ext%%'' |消息扩展,使用扩展的方式向推送中添加自定义字段,该值为固定值,不可修改。 | | ''%%em_alert_title%%'' | 推送通知的自定义标题。 | | ''%%em_alert_subTitle%%'' | 推送通知的自定义副标题。 | | ''%%em_alert_body%%'' |推送通知展示的自定义内容。 | **解析的内容** { "aps":{ "alert":{ "body":"custom push content" }, "badge":1, "sound":"default" }, "f":"6001", "t":"6006", "m":"373360335316321408", } ^参数 ^描述 ^ |''%%body%%'' |显示内容。 | |''%%badge%%'' |角标数。 | |''%%sound%%'' |提示铃声。 | |''%%f%%'' |消息发送方 ID。 | |''%%t%%'' |消息接收方 ID。 | |''%%m%%'' |消息 ID。 | ==== 自定义铃声 ==== 推送铃声是指用户收到推送时的提示音,你需要将音频文件加入到 app 中,并在推送中配置使用的音频文件名称。
- 支持格式 Linear PCM MA4 (IMA/ADPCM) µLaw aLaw。
- 音频文件存放路径 AppData/Library/Sounds,时长不得超过 30 秒。 更多内容可以参考苹果官方文档[[https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification?language=objc|Generating a Remote Notification.]] EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"test"]; EMChatMessage *message = [[EMChatMessage alloc] initWithConversationID:conversationId from:currentUsername to:conversationId body:body ext:nil]; message.ext = @{@"em_apns_ext":@{@"em_push_sound":@"custom.caf"}}; message.chatType = EMChatTypeChat; [EMClient.sharedClient.chatManager sendMessage:message progress:nil completion:nil]; ^参数 ^描述 ^ |''%%body%%'' |消息体。 | |''%%ConversationID%%'' |消息属于的会话 ID。 | |''%%from%%'' |消息发送方,一般为当前登录 ID。 | |''%%to%%'' |消息接收方 ID,一般与 ''%%ConversationID%%'' 一致。 | |''%%em_apns_ext%%'' |消息扩展,使用扩展的方式向推送中添加自定义字段,该值为固定值,不可修改。 | |''%%em_push_sound%%'' |自定义字段,用于设置自定义要显示的内容,该值为固定值,不可修改。 | |''%%custom.caf%%'' |音频文件名称。 | **解析的内容** { "aps":{ "alert":{ "body":"你有一条新消息" }, "badge":1, "sound":"custom.caf" }, "f":"6001", "t":"6006", "m":"373360335316321408" } ^参数 ^描述 ^ |''%%body%%'' |显示内容。 | |''%%badge%%'' |角标数。 | |''%%sound%%'' |提示铃声。 | |''%%f%%'' |消息发送方 ID。 | |''%%t%%'' |消息接收方 ID。 | |''%%m%%'' |消息 ID。 | ==== 强制推送 ==== 使用该方式设置后,本条消息会忽略接收方的免打扰设置,不论是否处于免打扰时间段都会正常向对方推送通知; EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"test"]; EMChatMessage *message = [[EMChatMessage alloc] initWithConversationID:conversationId from:currentUsername to:conversationId body:body ext:nil]; message.ext = @{@"em_force_notification":@YES}; message.chatType = EMChatTypeChat; [EMClient.sharedClient.chatManager sendMessage:message progress:nil completion:nil]; ^参数 ^描述 ^ |''%%body%%'' |消息体。 | |''%%ConversationID%%'' |消息属于的会话 ID。 | |''%%from%%'' |消息发送方,一般为当前登录 ID。 | |''%%to%%'' |消息接收方 ID,一般与 ''%%ConversationID%%'' 一致。 | |''%%em_force_notification%%'' |标志是否为强制推送的关键字,不可修改。 | ==== 基于 UNNotificationServiceExtension 的扩展功能 ==== 在 iOS10 之后生效,目的是为了唤醒 [[https://developer.apple.com/documentation/usernotifications/unnotificationserviceextension?language=objc|UNNotificationServiceExtension]],让你可以做更多的扩展。 EMTextMessageBody *body = [[EMTextMessageBody alloc] initWithText:@"test"]; EMChatMessage *message = [[EMChatMessage alloc] initWithConversationID:conversationId from:currentUsername to:conversationId body:body ext:nil]; message.ext = @{@"em_apns_ext":@{@"em_push_mutable_content":@YES}}; message.chatType = EMChatTypeChat; [EMClient.sharedClient.chatManager sendMessage:message progress:nil completion:nil]; ^参数 ^描述 ^ |''%%body%%'' |消息体。 | |''%%ConversationID%%'' |消息属于的会话 ID。 | |''%%from%%'' |消息发送方,一般为当前登录 ID。 | |''%%to%%'' |消息接收方 ID,一般与 ''%%ConversationID%%'' 一致。 | |''%%em_apns_ext%%'' |消息扩展,使用扩展的方式向推送中添加自定义字段,该值为固定值,不可修改。 | |''%%em_push_mutable_content%%'' |是否使用推送扩展的关键字,不可修改。 | **解析的内容** { "aps":{ "alert":{ "body":"test" }, "badge":1, "sound":"default", "mutable-content":1 }, "f":"6001", "t":"6006", "m":"373360335316321408" } ^参数 ^描述 ^ |''%%body%%'' |显示内容。 | |''%%badge%%'' |角标数。 | |''%%sound%%'' |提示铃声。 | |''%%mutable-content%%'' |苹果要求的关键字,存在之后才可唤醒 UNNotificationServiceExtension。 | |''%%f%%'' |消息发送方 ID。 | |''%%t%%'' |消息接收方 ID。 | |''%%m%%'' |消息 ID。 |