今天给大家介绍一下如何在iOS10下实现程序后台状态下,将接收到推送消息进行语音播报(demo见文章最后)
前言
前段时间在做XX银行O2O的商户端的时候其中有一个功能商户二维码收款。行方提的需求是希望跟支付宝收款的功能一样,在收款之后能够进行语音播报,说实话一开始还是比较懵逼的不知道该怎么实现。通过各种百度和探索发现i0S10下的UNNotificationServiceExtension+ AVSpeechSynthesizer实现这一功能。
之前项目也比较的忙没有来得及整理,最近时间稍微宽裕了点,就来跟大家分享一下是如何实现的顺便记录一下。
为项目集成推送
集成推送相对来说挺简单的,目前市面上的三方也挺多的,各种集成文档也挺多的。这里我就简单介绍一下如何集成推送。
1.配置推送证书
这个我这里就不说了网上挺多的也挺简单的
如果还是有同学不是很清楚 点这里
2.到三方平台创建应用并上传推送证书
此处需要注意推送的证书的bundleid要一致
3.为工程配置推送
开启推送.png4.设置后台
设置后台.png5.编写推送的代码(这里以个推为例)
代码挺多的我就不一一粘贴了如果你实在是不想写下载个demo一顿复制粘贴就行了
个推
极光
6.测试客户端能否顺利接收到推送消息
到三方推送的后台直接手动推送看能否接收到推送消息
拦截推送消息进行语音播报
新建一个UNNotificationServiceExtension
1、新建Target
屏幕快照 2017-10-13 下午3.22.13.png新建Target.png
然后下一步为新建的Target取个名字点击完成
这里需要注意的是这里的bundleID是你的工程名字的bundleID加上.新Target名称。
到这里新建Extension就完成了下面就开始写代码吧
2、实现播报代码
打开我们新建的Extension我们发现有三个文件
NotificationService.h
NotificationService.m
Info.plist
打开NotificationService.m我们会看到系统默认的代码
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
// Modify the notification content here...
self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.title];
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);
}
接下来我们就是要往delegate注入我们播报的代码了
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.contentHandler = contentHandler;
// copy发来的通知,开始做一些处理
self.bestAttemptContent = [request.content mutableCopy];
// Modify the notification content here...
// self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.title];
NSLog(@"userInfo----->%@",self.bestAttemptContent.userInfo[@"payload"]);
NSData *jsonData = [self.bestAttemptContent.userInfo[@"payload"] dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *pushdic = [NSJSONSerialization JSONObjectWithData:jsonData
options:NSJSONReadingMutableContainers
error:nil];
//这里我定义的Type 1--表示需要播报的推送 2--无需播报
//Content是需要播报的内容
if ([pushdic[@"Type"] isEqualToString:@"1"]) {
//开始语音播报
[self startSpeaking:pushdic[@"Content"]];
}
self.contentHandler(self.bestAttemptContent);
}
- (void)startSpeaking:(NSString *)words{
AVSpeechSynthesizer * synthsizer = [[AVSpeechSynthesizer alloc] init];
synthsizer.delegate = self;
AVSpeechUtterance * utterance = [[AVSpeechUtterance alloc] initWithString:words];//需要转换的文本
utterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"];//国家语言
utterance.rate = 0.6f;//声速
utterance.volume = 1;
[synthsizer speakUtterance:utterance];
}
到这里我们的基本功能就实现了,再到三方后台推送试一下。如果没有播报再回过头检查一下是不是哪一步出现了问题
细心的同学可能会发现有时候播报的声音大有时候播报的音量小。这里我们还需要优化一下,也就是我们自己来控制播报的音量。我找了一下。发现确实可以设置音量,但是私有API官方不允许使用即使用了也会被拒。
我找了一下,发现一个类MPMusicPlayerController。这个类有一个值,volume可以直接设置。接下来我们修改一下代码
- (void)startSpeaking:(NSString *)words{
AVSpeechSynthesizer * synthsizer = [[AVSpeechSynthesizer alloc] init];
synthsizer.delegate = self;
AVSpeechUtterance * utterance = [[AVSpeechUtterance alloc] initWithString:words];//需要转换的文本
utterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"];//国家语言
utterance.rate = 0.4f;//声速
utterance.volume = 1;
//修改播放时的音量 根据自己的需要来定
MPMusicPlayerController* musicController = [MPMusicPlayerController applicationMusicPlayer];
musicController.volume = 0.7;
[synthsizer speakUtterance:utterance];
}
到此本次分享就完成了,如果有哪位小伙伴还不是很明白可以留言或者私信我。如果小伙伴觉得这里还有什么不妥留下你的建议我们共同探讨 ~~
最后留下Demo有需要的可以去下载
网友评论
另外我发现在iOS10系统下用AVSpeechSynthesizer,控制台会输出许多莫名其妙的信息,而在iOS9系统下,就没有这些信息。