近期产品大大突然提出一个蛋疼的需求,并表示这是客户要求做的。。。没办法,只能硬着头皮上了。推送使用极光推送集成,集成方式详见极光官方文档。
实现原理
iOS 10以上采用推送扩展(极光必传mutable-content,iOS 10以下不需要)处理,使用iOS原生API AVSpeechSynthesizer实现文字合成语音。
iOS10以下采用固定音频文件播放,比如“你有一笔收款”。
相关代码
iOS 10以下:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { [JPUSHService handleRemoteNotification:userInfo]; completionHandler(UIBackgroundFetchResultNewData); // iOS 10之前前台没有通知栏 if ([UIDevice currentDevice].systemVersion.floatValue < 10.0 && [UIApplication sharedApplication].applicationState == UIApplicationStateActive) { // iOS 10以下 极光前台不展示消息栏,此处为自定义内容 [EBBannerView showWithContent:@"交易结果通知"]; // 获取共享域的偏好设置(详见多target数据共享) NSUserDefaults *userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.xxx"]; BOOL canSound = [userDefault boolForKey:@"voice"]; if (canSound) { // 播放refund.wav或collection.wav固定音频文件 if ([refund condition]) { [self playMusic:@"refund" type:@"wav"]; } else { [self playMusic:@"collection" type:@"wav"]; } } } }
// 播放音频文件 - (void)playMusic:(NSString *)name type:(NSString *)type { //得到音效文件的地址 NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:name ofType:type]; //将地址字符串转换成url NSURL *soundURL = [NSURL fileURLWithPath:soundFilePath]; //生成系统音效id AudioServicesCreateSystemSoundID((__bridge CFURLRef)soundURL, &_soundFileObject); //播放系统音效 AudioServicesPlaySystemSound(_soundFileObject); }
iOS 10及以上:
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler { self.contentHandler = contentHandler; self.bestAttemptContent = [request.content mutableCopy]; // iOS 10在有语音播报的情况下 可屏蔽系统提示音,也可根据需求来 self.bestAttemptContent.sound = nil; // Modify the notification content here... // 获取共享域的偏好设置 NSUserDefaults *userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group. xxx"]; // 解析推送自定义参数userInfo NSDictionary *userInfo = [self dictionaryWithUserInfo:self.bestAttemptContent.userInfo]; BOOL canSound = [userDefault boolForKey:@"voice"]; NSString *voiceString = nil; if (canSound) { if ([refund condition]) { voiceString = [NSString stringWithFormat:@"退款%@元!", userInfo[@"money"]]; } else { voiceString = [NSString stringWithFormat:@"收款%@元!", userInfo[@"money"]]; } } // 语音合成 [self syntheticVoice:voiceString]; self.contentHandler(self.bestAttemptContent); }
- (void)syntheticVoice:(NSString *)string { // 语音合成 self.synthesizer = [[AVSpeechSynthesizer alloc] init]; AVSpeechUtterance *speechUtterance = [AVSpeechUtterance speechUtteranceWithString:string]; //设置语言类别(不能被识别,返回值为nil) speechUtterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"]; //设置语速快慢 speechUtterance.rate = 0.55; //语音合成器会生成音频 [self.synthesizer speakUtterance:speechUtterance]; }