logo
当前页

Update a push notification

说明
本功能仅限在 iOS 设备上实现。

概述

在发送新通知的同时,您可以撤回原来推送通知内容。此功能常用于取消通话邀请通知,撤回消息等场景。

实现原理

ZPNs 支持通过发送 APNs 推送时携带 "mutable-content":1 字段,以便您的 APP 拦截该推送消息,修改其内容再展示,详情请参考 Apple Developer 官网文档对 mutable-content 的描述

配置 resourceID

联系 ZEGO 技术支持配置携带 "mutable-content":1 的 resourceID。

发送端

通过携带 ZIMPushConfig 的接口发送离线推送时,请将上述 resourceID 填入其中。

以发起呼叫邀请为例:

Untitled
var invitees = ['xxxx'];  // 被邀请人ID列表
var config = { 
    timeout: 60 ,//邀请超时时间,单位为秒,范围1-600   
    pushConfig:{
        title: 'push title',
        content: 'push content',
        payload: '{\"customId\":\"1\"}',// payload 携带一个自定的唯一标识符
        resourcesID: "携带 mutable-content 的 resourceID"
}}; 
zim.callInvite(invitees, config)
    .then(function({ callID, timeout, errorInvitees }){
        // 操作成功
        // 此处的 callID 是用户发起呼叫后,SDK 内部生成的 ID,用于唯一标识一次呼叫邀请;之后发起人取消呼叫、被邀请人接受/拒绝呼叫,都会使用此 callID
    })
    .catch(function(err){
        // 操作失败
    })
1
Copied!

接收端

1
配置 Capability

打开 Xcode,在 TARGETS 下选择目标,根据路径 Signing & Capabilities > Capabilities,开启 Push Notification(用于离线推送通知)。

2
设置 Notification Service Extension
1
添加 Notification Service Extension 到 Targets
  1. 点击 “File > New > Target...”

  2. 在弹窗中,选择 “iOS > Notification Service Extension”。

  3. 为该 Extension 输入 Product Name 等信息。

创建 Extension 后,会在项目工程中生成 "xxxExtension" 文件夹(xxx 为新增 Extension 时输入的 Product Name),您需要用到其中的 NotificationService 类文件。

2
为上述新增的 Extension 配置 Capability

在 TARGETS 下选择 Extension 目标,然后选择 “Signing & Capabilities > Capabilities > Push Notification”,即可开启离线推送通知。

3
调整上述新增的 Extension 支持的最低版本为 iOS 11.0 或以上

如果使用的设备 iOS 版本低于此处的版本,Extension 不会在此设备生效。

3
编写替换通知的逻辑

在 "xxxExtension" 文件夹(xxx 为新增 Extension 时输入的 Product Name)中的 NotificationService.m 文件中编写替换通知的业务逻辑,示例代码如下所示:

Untitled
//  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
1
Copied!

Previous

通知携带图片附件

Next

迁移方案