UNNotificationServiceExtension 简介:
UNNotificationServiceExtension 是iOS10
后推出的一个新特性:
从上面这张图片我们可以发现,在APNs
到App
推送中间添加Service Extension
,通过Service Extension
我们可以对推送内容进行处理,给用户展示更为丰富的通知内容显示.那么为什么苹果会在iOS10
后推出这个通知新特性呢?总结如下:
- 安全:
苹果总是把安全放在第一位,我们也知道苹果在iOS 9
开始鼓励我们使用更为安全的https协议.因为之前的推送大部分都是通过第三方机构推送,如果让心怀诡异的人进行抓包,数据也会暴露出来,这样我们可以在UNNotificationServiceExtension
类进行数据的处理. - 通知栏的内容展示更为丰富:
UNNotificationContentExtension
通知拓展类,可以给用户展现出一个有着丰富内容的通知,吸引用户点击通知进入到App
.
我们新建一个UNNotificationServiceExtension
:
这样在我们工程中就会看见一个文件夹,里面有2个文件,会默认生成2个方法,上代码:(下面实现在App进程杀死或者正在使用会播报本地一段音频文件音频长度不要超过30s
苹果限制了,否则无法播放音频文件)
#import "NotificationService.h"
#import <AVFoundation/AVFAudio.h>
#import <AudioToolbox/AudioToolbox.h>
@interface NotificationService ()
@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
@property (nonatomic, strong) AVSpeechSynthesizer *aVSpeechSynthesizer;
@end
@implementation NotificationService
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [哈哈]", self.bestAttemptContent.title];
self.bestAttemptContent.sound = nil;
NSDictionary *apns = self.bestAttemptContent.userInfo[@"aps"];
NSLog(@"apns = %@", apns);
if (apns) {
NSString *sound = apns[@"sound"][@"name"];
if (sound) {
NSString *path = [[NSBundle mainBundle] pathForResource:sound ofType:@"caf"];
static SystemSoundID soundID = 0;
NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
[[AVAudioSession sharedInstance] setActive:YES error:NULL];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:NULL];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)filePath, &soundID);
AudioServicesPlayAlertSoundWithCompletion(soundID, ^{
NSLog(@"播报完成");
});
}
}
self.contentHandler(self.bestAttemptContent);
}
- (void)serviceExtensionTimeWillExpire {
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
self.contentHandler(self.bestAttemptContent);
}
@end
接下来我们进行测试,我使用极光进行测试的 极光集成文档,集成好之后,我们在极光后台进行推送的时候"附加字段"这个选项里面一定添加"mutable-content": "1"
,否则可能会拦截通知失败(官方文档解释),以后需要后台推送的时候也要加上这个字段"mutable-content"
.
我在官网推送的自定义字段格式如下图: