新项目要用到推送,然后语音播报推送里的内容。比如支付宝的推送功能“支付宝到账100元”,这种的。
目前做这个的方法第一个想到的就是Notification Service Extension了,Notification Service Extension是ios10推出的新功能,所以只能在ios10及其以上的手机上有用。
Notification Service Extension的作用就是在苹果服务器在给手机推送消息的中间,进入Notification Service Extension, 我们可以在进Notification Service Extension时对推送的消息 进行一次加工,这就是Notification Service Extension的功能的作用。
推送流程
首先你要确定你已经接好了推送,可以收到推送了!
现在我们对Notification Service Extension进行创建:
第一步
第二步
这里说的不准确,Content Extension 是用来自定义推送UI和一些附加功能的 ,这么说比较好理解。
第二步,有自定义需求的可以吧两个都创建出来,不需要的只用创建Notification Service Extension就可以了。
第三步,创建成功之后,就会在项目中出现新创建的文件夹,里面有两个文件,
创建成功
这里要多说一句,创建成功之后,我们的Notification Service Extension的 Bundle Identifier应该是,原本的项目BundleIdentifier.XXX(Notification Service Extension的id),即原项目的Bundle Identifier.你的项目名,这是一个固定格式 不能出错。
第四部,创建好后,.m文件中 有两个方法,
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void(^)(UNNotificationContent *_Nonnull))contentHandler {}
- (void)serviceExtensionTimeWillExpire {}
我们在第一个方法里对通知进行处理,第二个方法是紧急方法,即第一个方法处理不完的时候就在第二个方法紧急处理,这个方法我还不是很了解具体的作用。
大家可以用下面这段代码测试一下,这里改变了通知的大标题,小标题,和内容:
- (void)didReceiveNotificationRequest:(UNNotificationRequest*)request withContentHandler:(void(^)(UNNotificationContent*_Nonnull))contentHandler {
self.contentHandler= contentHandler;
self.bestAttemptContent= [request.contentmutableCopy];
// Modify the notification content here...
// self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.title];
// 重写一些东西
self.bestAttemptContent.title = @"我是大标题";
self.bestAttemptContent.subtitle = @"我是小标题";
self.bestAttemptContent.body [email protected]"我是内容";
}
接下来就是简单的语音合成了,
#import <AVFoundation/AVFoundation.h>
@property (nonatomic, strong)AVSpeechSynthesizer *synthesizer;
- (void)didReceiveNotificationRequest:(UNNotificationRequest*)request withContentHandler:(void(^)(UNNotificationContent*_Nonnull))contentHandler {
self.contentHandler= contentHandler;
self.bestAttemptContent= [request.contentmutableCopy];
// Modify the notification content here...
// self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.title];
// 重写一些东西
NSDictionary*dict = self.bestAttemptContent.userInfo;
NSDictionary*notiDict = dict[@"aps"];
NSString*content = [notiDictvalueForKey:@"alert"];//这里取到我们通知的内容,字段和后台提前沟通好。
NSString*voiceString =nil;
voiceString = [NSStringstringWithFormat:@"%@", content];
[selfsyntheticVoice:voiceString];
self.contentHandler(self.bestAttemptContent);
}
- (void)syntheticVoice:(NSString*)string {
// 语音合成
self.synthesizer = [[AVSpeechSynthesizer alloc] init];
AVSpeechUtterance*speechUtterance = [AVSpeechUtterancespeechUtteranceWithString:string];
//设置语言类别(不能被识别,返回值为nil)
speechUtterance.voice= [AVSpeechSynthesisVoicevoiceWithLanguage:@"zh-CN"];
//设置语速快慢
speechUtterance.rate=0.5;//0.5是一个
//语音合成器会生成音频
[self.synthesizerspeakUtterance:speechUtterance];
}
这就是最简单的语音合成通知内容并播放了。
最后就是运行了:
运行项目
后面就是你可能会用到的tip了:
1.
2.我用的极光作为例子,这里自己测试的时候的选项,注意:这里很关键,一定要有"mutable-content": "1"这个字段,不然扩展是拦截不到你的推送的, 这个字段也要和推送内容字段在极光是Alert字段 在 同一级。这个要给后台说清楚不然拦截不到。
3.运行推送扩展你的断点不会起作用。
4.在我连线测试的时候,拦截到推送后就会崩溃,但是不连线测试就没问题,这个我也没找到原因。
5.不论你的调试是release还是debug,只要是连线运行上的项目都只能收到开发状态下的推送, 想收到生产状态下的推送 就需要到appstore,或者打测试包分发出来。