实现方式请参照 SealTalk 中的 ServiceExtension。
具体步骤如下:
给工程添加一个 target :Notification Service Extension。
主工程开启 Push Notifications 和 Background Modes 功能。
Service Extension target 开启 Push Notifications 功能。
NotificationService.m 中实现 - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler :
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
UNNotificationContent *content1 = request.content;
NSDictionary *userInfo = content1.userInfo;
NSDictionary *aps = [userInfo objectForKey:@"aps"];
NSString *category = [aps objectForKey:@"category"];
if (aps && category && [category isEqualToString:@"RC:RcCmd"]) {
NSString *appData = [userInfo objectForKey:@"appData"];
NSDictionary *appDataDic = [NSJSONSerialization JSONObjectWithData:[appData dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:nil];
NSString *idString = [appDataDic objectForKey:@"rc-dlt-identifier"];
if (idString) {
[[UNUserNotificationCenter currentNotificationCenter] getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) {
if (notifications.count == 0) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
self.contentHandler(self.bestAttemptContent);
});
return;
}
for (UNNotification *notice in notifications) {
UNNotificationRequest *request = notice.request;
UNNotificationContent *content = request.content;
NSDictionary *userInfo1 = content.userInfo;
NSString *identifier = userInfo1[@"rc"][@"id"];
if ([idString isEqualToString:identifier]) {
[[UNUserNotificationCenter currentNotificationCenter] removeDeliveredNotificationsWithIdentifiers:@[request.identifier]];
}
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
self.contentHandler(self.bestAttemptContent);
});
}];
}
} else {
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
self.contentHandler(self.bestAttemptContent);
}
}
撤回消息的推送内容示例:
{
appData = "{\"rc-dlt-identifier\":\"B7EE-8T9S-OI44-8NSS\"}";
aps =???? {
alert =???????? {
body = "\U4f60\U6536\U5230\U4e86\U4e00\U6761\U6d88\U606f";
};
badge = 2;
category = "RC:RcCmd";
"mutable-content" = 1;
sound = "aaaaaa.caf";
};
rc =???? {
cType = PR;
fId = 1xTlsmAn9;
id = "B7EE-918C-GI64-8NSS";
oName = "RC:RcCmd";
sourceType = 0;
tId = 1xTlsmAn9;
};
richMediaUri = "";
}
其中通过 aps 中的 category 判断是不是撤回消息,如果是撤回消息,appData 中的 rc-dlt-identifier 表示要撤回消息的 id 。
注:
只有公有云支持该功能;
该功能只在 iOS 10 以上有效。