Update a push notification
概述
在发送新通知的同时,您可以撤回原来推送通知内容。此功能常用于取消通话邀请通知,撤回消息等场景。
实现原理
ZPNs 支持通过发送 APNs 推送时携带 "mutable-content":1
字段,以便您的 APP 拦截该推送消息,修改其内容再展示,详情请参考 Apple Developer 官网文档对 mutable-content 的描述。
配置 resourceID
联系 ZEGO 技术支持配置携带 "mutable-content":1
的 resourceID。
发送端
通过携带 ZIMPushConfig 的接口发送离线推送时,请将上述 resourceID
填入其中。
以发起呼叫邀请为例:
ZIMCallInviteConfig *config = [[ZIMCallInviteConfig alloc] init];
config.timeout = 60;
config.mode = ZIMCallInvitationModeGeneral;
ZIMPushConfig *pushConfig = [[ZIMPushConfig alloc] init];
pushConfig.resourcesID = KeyCenter.resourceID;
pushConfig.title = [ZGZIMManager shared].myUserID;
pushConfig.content = @"邀请你语音通话";
// payload 携带一个自定的唯一标识符
pushConfig.payload = @"{\"customId\":\"1\"}";
config.pushConfig = pushConfig;
// 发起呼叫邀请
[[ZGZIMManager shared] callInviteWithInvitees:self.selectMemberList config:config callback:^(NSString * _Nonnull callID, ZIMCallInvitationSentInfo * _Nonnull info, ZIMError * _Nonnull errorInfo) {}];
接收端
打开 Xcode,在 TARGETS 下选择目标,根据路径 Signing & Capabilities > Capabilities,开启 Push Notification(用于离线推送通知)。
-
点击 “File > New > Target...”
-
在弹窗中,选择 “iOS > Notification Service Extension”。
-
为该 Extension 输入 Product Name 等信息。
创建 Extension 后,会在项目工程中生成 "xxxExtension" 文件夹(xxx 为新增 Extension 时输入的 Product Name),您需要用到其中的 NotificationService 类文件。
在 TARGETS 下选择 Extension 目标,然后选择 “Signing & Capabilities > Capabilities > Push Notification”,即可开启离线推送通知。
如果使用的设备 iOS 版本低于此处的版本,Extension 不会在此设备生效。
在 "xxxExtension" 文件夹(xxx 为新增 Extension 时输入的 Product Name)中的 NotificationService.m 文件中编写替换通知的业务逻辑,示例代码如下所示:
// NotificationService.m
// NotificationService
#import "NotificationService.h"
#import <Intents/Intents.h>
@interface NotificationService ()
@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
@end
@implementation NotificationService
// 开启推送拦截后,收到携带 "mutable-content":1 的推送通知时,会触发该方法。
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
// 标题
NSString *title = self.bestAttemptContent.title;
// 副标题
NSString *subtitle = self.bestAttemptContent.subtitle;
// 内容
NSString *body = self.bestAttemptContent.body;
// 取出发送推送消息附带的 payload 字符串
NSString *payload = [self.bestAttemptContent.userInfo objectForKey:@"payload"];
if(payload == nil){
self.contentHandler(self.bestAttemptContent);
return;
}
// 解析 json 字符串,并转为 NSDictionary
NSData *jsonData = [payload dataUsingEncoding:NSUTF8StringEncoding];
NSError *error = nil;
NSDictionary *payload_json_map = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
if (error) {
self.contentHandler(self.bestAttemptContent);
return;
}
// 取出 payload 携带的唯一标识符
NSString *customId = [payload_json_map objectForKey:@"customId"];
if(customId != nil){
[UNUserNotificationCenter.currentNotificationCenter getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) {
NSString *target_id = nil;
// 遍历已存在的通知,找到唯一标识符一致的通知后,删除
for (int index = 0; index < notifications.count; index ++) {
if([[notifications[index].request.content.userInfo objectForKey:@"customId"] isEqual: customId]){
target_id = notifications[index].request.identifier;
break;
}
}
if(target_id != nil){
[UNUserNotificationCenter.currentNotificationCenter removeDeliveredNotificationsWithIdentifiers:@[target_id]];
}
contentHandler(self.bestAttemptContent);
}];
}else{
contentHandler(self.bestAttemptContent);
}
}
@end