iOS 推送语音播报(类似支付宝微信的收款提醒)

项目需求:

近期项目有个需求,实现类似支付宝微信收款后的语音播报如:支付宝到账xx元。要求是APP在前台运行、锁屏、杀死进程后都会有语音播报。

预想方案:

1.通过UIBackgroundTaskIdentifier不断向程序索要处理时间(这种方案不知道以前可行,现在好像是最多只能保持3分钟的时间,一般30s左右)-fail

2.后台播放无声音,保持APP一直运行,但是上架APPStore一般不是音乐类的都无法过审–fail

 

因此,我们现在选择了远程推送实现需求:(附DEMO)

3.通过远程推送,在iOS10的时候,发布了UNNotificationServiceExtension扩展,关于此扩展,可以网上选择一些资料iOS10 推送extension之 Service Extension,主要的核心思想就是,在远程推送到底设备之前,给你一个修改的机会,我们知道,推送体是有限制的,而且推送体大小也会影响推送的效率,借助这个,我们可以修改标题、内容,也可以从网络上请求到内容,再去合成一个新的推送。

接下来就是实现手机接收到通知之后播报语音了,关于这个功能的实现在iOS10以后苹果新增了“推送拓展”UNNotificationServiceExtension,我们可以在这里操作,在这里我用的是苹果官方的AVSpeechSynthesizerAVSpeechUtterance来将接收到的推送内容转换成语音播报

貌似没啥问题,但是iOS12.1以后,不在允许在UNNotificationServiceExtension中播放语音了,只有系统提示音,阿欧。。。心好累。。。,没办法只好先在想办法,上网查找资料发现前辈们果然有解决办法,哈哈。。。

1.配置远程推送

2.在收到远程推送时,调用本地推送

3.把播报金额拆分成,一、二、三,四、五…千、百、万、点、元等一个个音频文件,根据推送过来的金额进行进行筛选然后按照顺序放入数组,具体的在下面有介绍(caculateNumber方法处理)

4.循环(递归)发送本地推送播放项目中的音乐文件

重点:

功能实现

1.配置 UNNotificationServiceExtension

具体的配置可参考文档:iOS10 推送extension之 Service Extension你玩过了吗?,这里不在啰嗦了

2.配置好之后,然后我们在AppDelegate里面进行通知的注册,核心代码

// 注册推送
- (void)registerRemoteNotification{
UIApplication *application = [UIApplication sharedApplication];
application.applicationIconBadgeNumber = 0;

if([application respondsToSelector:@selector(registerUserNotificationSettings:)])
{
UIUserNotificationType notificationTypes = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:notificationTypes categories:nil];
[application registerUserNotificationSettings:settings];
}

#if !TARGET_IPHONE_SIMULATOR
//iOS8 注册APNS
if ([application respondsToSelector:@selector(registerForRemoteNotifications)]) {
[application registerForRemoteNotifications];
}else{
UIRemoteNotificationType notificationTypes = UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound |
UIRemoteNotificationTypeAlert;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:notificationTypes];
}
#endif
}

3.然后我们在NotificationService.m文件内写入收到json数据解析,获取推送金额并处理,得到语音文件的数组,并播放语音(本地推送 -音频)文件

代码如下:


#import "NotificationService.h"
#import "XSAudioManager.h"
#import <AVFoundation/AVFoundation.h>
#define kFileManager [NSFileManager defaultManager]

typedef void(^PlayVoiceBlock)(void);

@interface NotificationService ()<AVAudioPlayerDelegate,AVSpeechSynthesizerDelegate>
{
AVSpeechSynthesizer *synthesizer;
}
@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
// AVSpeechSynthesisVoice 播放完毕之后的回调block
@property (nonatomic, copy)PlayVoiceBlock finshBlock;

//声音文件的播放器
@property (nonatomic, strong)AVAudioPlayer *myPlayer;
//声音文件的路径
@property (nonatomic, strong) NSString *filePath;

@end

@implementation NotificationService

/*
*后台推送的json案例
{"aps":{"alert":"钱到啦收款10000元","badge":1,"mutable-content":1,"amount":10000, "sound":"default"}}
*/

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];

// Modify the notification content here...

//step1: 推送json解析,获取推送金额
NSMutableDictionary *dict = [self.bestAttemptContent.userInfo mutableCopy] ;
NSDictionary *extras = [dict objectForKey:@"aps"] ;
BOOL playaudio = [[extras objectForKey:@"amount"] boolValue] ;
if(playaudio) {

//step2:先处理金额,得到语音文件的数组,并播放语音(本地推送 -音频)
NSString *amount = [extras objectForKey:@"amount"] ;//10000
NSArray *musicArr = [[XSAudioManager sharedInstance] getMusicArrayWithNum:amount];
__weak __typeof(self)weakSelf = self;
[[XSAudioManager sharedInstance] pushLocalNotificationToApp:0 withArray:musicArr completed:^{
// 播放完成后,通知系统
weakSelf.contentHandler(weakSelf.bestAttemptContent);
}];

} else {
//系统通知
self.contentHandler(self.bestAttemptContent);
}
}

// 30s的处理时间即将结束时,该方法会被调用,最后一次提醒用户去做处理
- (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);
}

@end

 

我们定义了一个声音处理的中间类XSAudioManager,因为扩展和APP本身都会使用这个类,所以新建这个文件的时候,注意勾选Targets

XSAudioManager.h

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

// 处理完成的callback
typedef void (^XSNotificationPushCompleted)(void) ;

@interface XSAudioManager : NSObject

+ (instancetype)sharedInstance;

//先处理金额,得到语音文件的数组
-(NSArray *)getMusicArrayWithNum:(NSString *)numStr;

//循环调用本地通知,播放音频文件
-(void)pushLocalNotificationToApp:(NSInteger)index withArray:(NSArray *)tmparray completed:(XSNotificationPushCompleted)completed;

/*
**系统的语音播报(红包消息)
*AVSpeechSynthesizer(iOS10.0-12.0),之后不支持播报
*/
- (void)speechWalllentMessage:(NSString *)numStr;

@end

NS_ASSUME_NONNULL_END

4.APP在前台的时候是没有声音的,前台需要走正常的推送解析,走正常的语音播报,调用系统的播报方法。

//语音播报红包消息
- (void)speechWalllentMessage:(NSString *)numStr {

//播放语音
// 合成器 控制播放,暂停
AVSpeechSynthesizer *_synthesizer;
// 实例化说话的语言,说中文、英文
AVSpeechSynthesisVoice *_voice;
_voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh_CN"];
// 要朗诵,需要一个语音合成器
_synthesizer = [[AVSpeechSynthesizer alloc] init];
AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:[NSString stringWithFormat:@"XX到账%@元",numStr]];
//指定语音,和朗诵速度
utterance.voice = _voice;
// utterance.rate = AVSpeechUtteranceDefaultSpeechRate;
utterance.rate = 0.55;
utterance.pitchMultiplier = 1.0f; //改变音调
// utterance.volume = 1;
//启动
[_synthesizer speakUtterance:utterance];

}

至此,语音播报算是完成了。

 

在iOS12.1以上,远程推送+本地推送,前台可以正常播放,后台、退出的情况下,播放收款到账提醒。

 

注意事项:
1、在项目target-Capabilities-Background Modes中要记得勾选Remote notifications 这样设置才可以正常接收推送。并且在设置推送的时候,一定要带上这个字段:"mutable -content" ,只有将该字段设置为1,才可以正常实现功能。

2.音乐文件要导入的时候,在target和NotificationServiceExtension的:Build Phases --> Copy BumdleResources-->add资源文件

 

3.模拟推送可以选择pusher工具模拟测试,附Git地址:pusher,需要选择推送证书和手机的DeviceToken

因为之前没有做过此类功能,也是借鉴了很多大牛的解决方案,每个借鉴都有带的链接,如果有侵权请联系我删除。目前就总结这么多,有更好的想法希望可以在评论里一起交流。

 

参考文档:

iOS 12.1 语音播报问题

iOS开发 - 语音播报功能的实现

 

测试代码:DEMO

 

 

 

原创:https://www.panoramacn.com
源码网提供WordPress源码,帝国CMS源码discuz源码,微信小程序,小说源码,杰奇源码,thinkphp源码,ecshop模板源码,微擎模板源码,dede源码,织梦源码等。

专业搭建小说网站,小说程序,杰奇系列,微信小说系列,app系列小说

iOS 推送语音播报(类似支付宝微信的收款提醒)

免责声明,若由于商用引起版权纠纷,一切责任均由使用者承担。

您必须遵守我们的协议,如果您下载了该资源行为将被视为对《免责声明》全部内容的认可-> 联系客服 投诉资源
www.panoramacn.com资源全部来自互联网收集,仅供用于学习和交流,请勿用于商业用途。如有侵权、不妥之处,请联系站长并出示版权证明以便删除。 敬请谅解! 侵权删帖/违法举报/投稿等事物联系邮箱:2640602276@qq.com
未经允许不得转载:书荒源码源码网每日更新网站源码模板! » iOS 推送语音播报(类似支付宝微信的收款提醒)
关注我们小说电影免费看
关注我们,获取更多的全网素材资源,有趣有料!
120000+人已关注
分享到:
赞(0) 打赏

评论抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

您的打赏就是我分享的动力!

支付宝扫一扫打赏

微信扫一扫打赏