iOS15 消息推送语言播报【修订版】(处于后台/被杀死的状态仍可进行语言播报)

505 阅读3分钟

“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 8 天,点击查看活动详情

引言

  1. 付费方案(付费离线SDK+Service Extension):kunnan.blog.csdn.net/article/det…

  2. 免费方案:(本地拼接音频+Service Extension)download.csdn.net/download/u0…

采用语音合成音频文件后,将文件写到AppGroups的Library/Sounds文件夹下,最后更改UNNotificationSound属性来自定义的收款到账语音。

如果无法下载,可通过添加WX:iosrev

修订版demo:iOS15 消息推送语言播报【修订版】(处于后台/被杀死的状态仍可进行语言播报)

download.csdn.net/download/u0…

原理: 本地离线合成音频+Service Extension

⭕ 解决离线合成比较成本昂贵问题:采用本地拼接音频实现。

⭕ 解决iOS15之后本地通知通知栏弹出多次的问题:使用Service Extension拦截消息推送,修改UNNotificationSound为本地拼接的音频,来避免产生多条横幅。

合并的音频保存在AppGroup:

⭕ 解决金额转换为对应的文字的细节问题(numFormatter的兼容处理)

I 后台语音播报推送信息

1.1 实现原理

iOS12.1 以下使用AVAudioPlayer进行语音播报,iOS12.1 - iOS14 可以使用本地通知进行语音播报,iOS15 通过修改推送sounds字段来播报自定义的语音。

  1. 在iOS10中推出的Notification Service Extension(以下简称NSE),当apns的payload上带上"mutable-content"的值为1时,就会进入NSE的代码中。

  2. 在NSE中通过给UNNotificationContent中的Sound属性赋值来达到在通知弹出时播放一段自定义音频的目的。

利用离线合成或者从后台下载的方式,生成需要播报的内容,通过自定义通知铃声的方式,达到语音播报提醒的目的。

  1. 音频存储在AppGroups中: 通过离线语音合成库生成wav音频文件后,将文件写到AppGroups的Library/Sounds文件夹下,最后更改UNNotificationSound属性即可使通知播报一段自定义的收款到账语音。在这里插入图片描述 扩展和主应用都要配置AppGroupsID,否则获取不到groupURL。 在这里插入图片描述
    NSURL *groupURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:kAppGroupID];

1.2 推送语音播报总控制逻辑


- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.contentHandler = contentHandler;
    UNMutableNotificationContent *bestAttemptContent = [request.content mutableCopy];
    
    
    
    NSLog(@"NotificationService_%@: dict->%@", NSStringFromClass([self class]), bestAttemptContent.userInfo);
    
    
    bestAttemptContent.sound = nil;
    
    

    
    [YJAudioTool.sharedPlayer.userInfos addObject: bestAttemptContent];
    
    
    if (@available(iOS 15.0, *)) {
        
//        self.contentHandler(bestAttemptContent);
        // 调用iOS15之后的递归方法处理消息
         [self processNotificationContent4ios15];
        
        

        return;
    }
    

    
    
    // 调用iOS14之前的递归方法处理消息
     [self processNotificationContent];


        
}

  1. 原来iOS14之前的旧方式实现demo下载地址:download.csdn.net/download/u0…

  2. iOS15的实现demo下载地址:download.csdn.net/download/u0…

- (void)processNotificationContent4ios15{
    __weak __typeof__(self) weakSelf = self;
    
    if(YJAudioTool.sharedPlayer.userInfos.count<1){// 递归的退出条件
        return ;
    }
    
请查看原文:https://blog.csdn.net/z929118967/article/details/123325914

}


1.3 合并音频到在AppGroup中

合并音频:

  1. sourceURLsArr的元素是全路径 NSString *mp3Path1 = [[NSBundle mainBundle] pathForResource:audioFileURL ofType:nil];
  2. AppGroups共享目录: NSURL *groupURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:kAppGroupID];

- (void)mergeAVAssetWithSourceURLs:(NSArray *)sourceURLsArr completed:(void (^)(NSString * soundName,NSURL * soundsFileURL)) completed{
    //创建音频轨道,并获取多个音频素材的轨道
    AVMutableComposition *composition = [AVMutableComposition composition];
请查看原文:https://blog.csdn.net/z929118967/article/details/123325914

}

通过NSFileManager把输出音频保存在【AppGroup】的/Library/Sounds/里面.

AVAssetExportSession的输出路径必须要保证文件夹存在,不然会提示操作有误。

II 实现细节

将金额转换为对应的文字(numFormatter的兼容处理)

blog.csdn.net/z929118967/… 在这里插入图片描述 查找金额文字对应的音频文件

+ (NSString *)audioFileWithString:(NSString *)fileName {
      if([fileName isEqualToString:@"零"] || [fileName isEqualToString:@"〇"]) return @"tts_0.mp3";//兼容0
//https://kunnan.blog.csdn.net/article/details/123330008
}

iOS15 消息推送语言播报【修订版】(处于后台/被杀死的状态仍可进行语言播报)

download.csdn.net/download/u0…

原理: 本地离线合成音频+Service Extension

⭕ 解决离线合成比较成本昂贵问题:采用本地拼接音频实现。

⭕ 解决iOS15之后本地通知通知栏弹出多次的问题:使用Service Extension拦截消息推送,修改UNNotificationSound为本地拼接的音频,来避免产生多条横幅。

合并的音频保存在AppGroup:

⭕ 解决金额转换为对应的文字的细节问题(numFormatter的兼容处理)

———————————————— 版权声明:本文为CSDN博主「iOS逆向」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/z929118967/…