APNs 离线推送(已废弃)
更新时间: 2023/07/21 06:56:02
本文已废弃,请前往实现 APNs 离线推送等推送文档查看相关说明。
APNs推送
前期准备
创建请求证书
-
在 OSX 系统中点击“钥匙串访问”,生成请求证书。
-
在证书信息中填入常用邮件地址,选择保存到磁盘。
创建应用AppID
- 登陆 iOS Dev Center 选择进入 Certificates,Identifiers & Profiles。
- 点击左栏 iOS Apps IDs ,进入 Identifiers - App IDs 列表
- 点击右侧 “+” 号,创建 App ID
开启推送功能
-
点击创建好的 App,选择 Edit 按钮。
-
勾选 Push Notifications 功能,点击配置证书按钮,进入配置证书页面。请注意开发证书的种类,开发证书供开发调试使用,生产证书供发布使用。
配置证书
- 将刚刚生成的请求证书(CSR文件)上传,点击 Generate。
-
完成后下载并打开证书,会将证书自动导入钥匙串。
在“钥匙串访问中”的“我的证书”里可以找到刚刚导入的证书。
导出推送所需p12文件
- 选择刚刚导进来的证书,选择右键菜单中的导出选项。
- 保存 p12 文件时,请设置密码,上传证书时需要填写密码。
证书上传
- 进入网易云信控制台,选择对应的应用,进入
证书管理
->iOS推送证书
。 - 按图中所示,上传刚刚导出的 p12 文件。可以上传多个 p12 文件,以上传时所填入的证书名称做区分。
- ⽣产环境(线上环境)或 开发环境(测试环境),请选择与该证书⽣成时相同的环境类型。
客户端配置
配置推送证书
在初始化中NIMIOSSDKOptions
设置对应的推送证书名。
示例代码:
dart
final options = Platform.isAndroid
? NIMAndroidSDKOptions(
appKey: 'appkey',
/// 其他 通用/Android 配置
)
: NIMIOSSDKOptions(
appKey: 'appkey',
apnsCername: 'apnsCername', //推送证书名
/// 其他通用配置/iOS 配置
);
NimCore.instance.initialize(options)
.then((result){
if (result.isSuccess) {
/// 初始化成功
} else {
/// 初始化失败
}
});
上传devicetoken
客户端还需要将 devicetoken 上传至云信服务器用于后续的 APNs 推送,需要使用以下接口:
dart/// 更新iOS deviceToken
/// [token] 当前设备的 devicetoken
/// [customContentKey] 自定义本端推送内容, 设置key可对应业务服务器自定义推送文案; 传空字符串清空配置, null 则不更改
Future<NIMResult<void>> updateAPNSToken(Uint8List token, String? customContentKey);
上传 devicetoken 的具体步骤如下:
-
在原生层获取 deviceToken,并将 deviceToken 上传到 dart 层。
在 Runner 工程下的 AppDelegate.swift 文件中添加如下代码:
override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let flutterData = FlutterStandardTypedData.init(bytes: deviceToken) let controller : FlutterViewController = window?.rootViewController as! FlutterViewController let methodChannel = FlutterMethodChannel(name: "com.netease.NIM.demo/settings", binaryMessenger: controller.binaryMessenger) methodChannel.invokeMethod("updateAPNsToken", arguments: flutterData) }
其中
com.netease.NIM.demo/settings
为methodChannel
名字,客户自己定义即可,但需要同 dart 层保持一致。 -
在 dart 层注册
methodChannel
,并接收原生层上传的 deviceToken。MethodChannel('com.netease.NIM.demo/settings') .setMethodCallHandler((call) async { if (call.method == 'updateAPNsToken') { print('update APNs token'); _deviceToken = call.arguments as Uint8List; } return null; });
-
在 dart 层初始化
nim_core
成功之后,调用updateAPNSToken
方法更新 deviceToken。void updateAPNsToken() { if (NimCore.instance.isInitialized && Platform.isIOS && _deviceToken != null) { NimCore.instance.settingsService.updateAPNSToken(_deviceToken!, null); } }
角标未读数
角标未读数赋值
默认情况下,每一条消息的推送会让应用角标未读数加 1 。 如当应用处于后台时,收到5条消息推送,则应用的角标未读数增加5。
消息的发送方在发送消息时,可以通过NIMMessage - NIMCustomMessageConfig - enableUnreadCount
设置该消息推送时是否要计入角标未读数。
苹果推送所附带的未读数是通过设置推送 payload 里的 badge 参数。在云信 服务中,不支持直接设置 badge ,服务器会维护对每个用户维护一个当前未读数,当服务器收到一条未读消息后,会自动在未读数上累加后填入推送的 badge 字段推送给接收端。
角标未读数上限
云信侧发起的推送可以配置iOS应用角标未读数上限,配置位置:云信控制台 > 选择应用 > IM专业版/IM免费版 > 功能配置 > iOS应用角标未读数上限配置
。
推送铃声设置
消息推送的声音设置支持自定义,类似于推送的 payload , 开发者只需设置NIMMessage - pushPayload
,在其中插入一对键为sound
的键值对。需要注意推送音频的具体格式,具体请参考苹果官方文档。
示例
dartvar message = NIMMessage(messageType: NIMMessageType.text, timestamp: 0, messageDirection: NIMMessageDirection.outgoing);
message.content = '消息示例';
message.pushContent = '发来了一条信息';
message.pushPayload = {'sound':'message.wav'};
推送标题设置
目前云信发起的APNs推送支持两种方式设置推送标题:
- 设置
NIMMessage - pushPayload - apsField - alert
中的title
和body
两个key可以指定推送标题与推送文案,此优先级最高。特别地,如果配置了apsField
的alert
字段,但是title
为空或没有配置将没有推送标题,body
为空或没有配置将没有推送文案,两者都为空或都没有配置则推送标题和推送文案都没有。具体可见下方示例。 - 如果没有在
apsField
中配置,但是通过payload
配置了"pushTitle": "标题内容"
,则以此显示。 - 如果都没有配置,则不会显示推送标题。
开发者无法在推送参数payload中配置aps字段,IM提供推送配置payload - apsField字段,对应APNs的payload - aps字段。该字段仅适用于iOS接收,Android无法解析此字段。下面展示通过IM配置的带有apsField字段的payload:
json{
// 上述示例代码出于展示目的进行了格式化,实际发送的时候不要进行格式化。
"key1": "value1", //自定义键值对
"apsField": {
"mutable-content": 1,
"sound": "abc.wav",
"alert": {
"title": "推送标题",
"body": "推送内容"
},
"key2": "value2"
}
}
点击通知栏跳转
当收到APNs推送后,用户点击通知栏后,希望进入指定的聊天界面时,可以参考如下方案:
发送方在构造消息对象时,在NIMMessage - pushPayload
中插入表示会话标识的信息(如自身的账号、群id、会话类型等),便于接收端获取到APNs - payload
时解析。如:
json{
// 上述示例代码出于展示目的进行了格式化,实际发送的时候不要进行格式化。
"sessionid": "zhangsan", //表明该条消息的发送者的账号或者消息所属的群组id
"sessiontype": "p2p", //表明条消息对应的会话是单聊还是群聊等等
"apsField": {
"mutable-content": 1,
"sound": "abc.wav",
"alert": {
"title": "推送标题",
"body": "推送内容"
},
"key2": "value2"
}
}
当接收端收到APNs推送时,解析APNs - payload
得到sessionid
和sessiontype
,并跳转到对应的界面。
通知栏内容覆盖
iOS 10及以上支持推送消息覆盖,即后一条推送内容覆盖前面推送内容。一种典型的场景是撤回消息的情况:
A发消息给B,产生APNs推送,文案内容为“你好“。然后A撤回了这条消息,此时通知栏中的“你好”变为预设的“对方撤回了一条消息”。
一种建议的实现方式是:
- 在发送消息时,需要在
NIMMessage - pushPayload
中插入key
为apns-collapse-id
的键值对,value
的内容建议使用uuid等字符串,用以唯一标识该消息。 - 当要撤回这条消息时,在撤回接口传参
apnsContent
中设置覆盖文案,在pushPayload
中插入与被撤回消息相同的apns-collapse-id
。
注意:这里以iOS-SDK为例,当其他端发起撤回消息时,也是如此。
示例:
dartvar pushPayload = {'apns-collapse-id':'id'};
var message = NIMMessage(messageType: NIMMessageType.text, timestamp: 0, messageDirection: NIMMessageDirection.outgoing);
message.pushPayload = pushPayload;
NimCore.instance.messageService.revokeMessage(message: message);