近期无知经理突然提出一个蛋疼的需求,并表示这是“客户和市场强制要求”做的。。。没办法,只能硬着头皮上了。
之前采用的是静默推送+普通推送,而且网上大部分资料也默认使用的是静默推送方式。据我所知,该方案有一定的缺陷:
1.部分机器收不到语音播报;
2.若需要在后台或锁屏状态下播报语音时,上架会遇到"Audio,AirPlay,and Picture in Picture"和"Background fetch"等问题审核被拒。通过查阅网上的资料,我改用iOS 10新的API推送扩展(UNNotificationServiceExtension),三方SDK使用极光,关于集成方式就不多说了,详见极光官方文档。
这种方案的特点是:节省大量代码,上架简单,服务器只需要推一条消息,但iOS 10以上"mutable-content = 1"必传,否则程序不走这个扩展的Target。
实现原理
iOS 10以上采用推送扩展(极光必传mutable-content,iOS 10以下不需要)处理,使用iOS原生API AVSpeechSynthesizer实现文字合成语音。
iOS10以下采用固定音频文件播放,比如“您有一条新订单,请及时处理!”。
相关代码
- (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); }
君凯商联网-iOS-字唐名僧- (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]; }
版权声明:本文为u010960265原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。