iOS 收款推送消息语音播报

  近期产品大大突然提出一个蛋疼的需求,并表示这是“客户和市场强制要求”做的。。。没办法,只能硬着头皮上了。
  之前采用的是静默推送+普通推送,而且网上大部分资料也默认使用的是静默推送方式。据我所知,该方案有一定的缺陷: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实现文字合成语音。


    iOS 收款推送消息语音播报_第2张图片
    屏幕快照 2017-12-04 09.53.17.jpg

  • 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];
}

你可能感兴趣的:(iOS 收款推送消息语音播报)