最近申请了支付宝的二维码收钱码,其中支付宝有这么一个功能,就是,别人扫描你的二维码给你转账之后,收到钱会有一条语音推送,”支付宝到账 1000万“之类的推送消息,不管你的支付宝app有没有被杀死。

只要你的远程推送开着,并且支付宝的"二维码收钱到账语音提醒",都打开着,就可以收到。

打开方式:支付宝点击右上角设置-通用-新消息通知,打开到账提醒即可。

image.png

并且别人给你转多少钱就会播报到账多少钱。

探索实现一下。

当前有两种方案实现了上面描述的场景。

必备条件
上面的描述场景只有在iOS10以上版本才可以,因为必须要基于Notification Servivice Extension

image.png

如果对Notification Servivice Extension不是很熟悉的,建议先了解一下
iOS10 推送extension之 Service Extension你玩过了吗?

实现方式
1、ServiceExtension中收到推送之后,用AVSpeechSynthesisVoice相关类,直接把推送过来需要播报相关的文字转化成语音播报
2、ServiceExtension中收到推送之后,将要播报的数字,找到对应的单个音频,排序,用拼接音频的方式<通过推送过来的文字去查找相关的音频,然后拼接成一个音频>,然后使用AudioServicesCreateSystemSoundID播放

在介绍相关方式之前,先介绍一个测试工具
SmartPush

使用方式也很简单,应该一看就懂

image.png


正式进入主题
方式一

@implementation NotificationService- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {self.contentHandler = contentHandler;self.bestAttemptContent = [request.content mutableCopy];// Modify the notification content here...self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.title];self.contentHandler(self.bestAttemptContent);[self playVoiceWithAVSpeechSynthesisVoiceWithContent:self.bestAttemptContent.body];}- (void)playVoiceWithAVSpeechSynthesisVoiceWithContent:(NSString *)content
{if (content.length == 0) {return;}// 创建嗓音,指定嗓音不存在则返回nilAVSpeechSynthesisVoice *voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"];// 创建语音合成器AVSpeechSynthesizer *synthesizer = [[AVSpeechSynthesizer alloc] init];// 实例化发声的对象AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:content];utterance.voice = voice;utterance.rate = 0.5; // 语速// 朗读的内容[synthesizer speakUtterance:utterance];
}

推送的内容是:

{"aps":{"alert":{"title":"iOS 10 title","subtitle":"iOS 10 subtitle","body":"世上只有妈妈好,有妈的孩子像块宝。投进妈妈的怀抱,幸福哪里找。没妈的孩子像根草"},"my-attachment":"http://img01.taopic.com/160317/240440-16031FU23937.jpg","mutable-content":1,"category":"myNotificationCategory1","badge":3}
}

坑点
说明:当前实现的是将push内容中的body播放出来
1、如果你收到推送了但是添加了系统的铃声,也就是你在push的json中添加了"sound":"default"那么就可能会影响推送声音的播放
2、收到推送了,但是没有播报语音,检查一下这里

image.png
3、播放的声音时间长度,经过测试最多是5秒钟,这里应该是苹果做了限制,拿上面的推送内容举例子"body":"世上只有妈妈好,有妈的孩子像块宝。投进妈妈的怀抱,幸福哪里找。没妈的孩子像根草",最多也就是播放到世上只有妈妈好,有妈的孩子像块宝。投进妈妈的怀抱


方式二
经过对比,支付宝播放的声音明显比系统方法文字转语音播放的好听,一听就是小姑娘录得。要么就是自己集成了一套文字转语音的东西。
首先尝试使用科大讯飞来实现,结果失败了。
然后尝试的是语音合成的方式来播放
比如提前先录好 以下可能播报的内容


支付宝到账、 0、 1、 2、 3、 4、 5、 6、 7、 8、 9、 十、 百、 千、 万、 十万、 百万、 千万、 亿、 元 等等


这样的几种录音,然后用相关的名字命名好<相关的规则自己命名就好>。
比如push过来的是内容是 10010,那么转化成的录音文件名称的数组就是
@[@"支付宝到账",@"1",@"万",@"0",@"1",@"十",@"元"]
然后找到这几个文件,然后按照顺序拼接成一个语音文件进行播放

代码演示:

@implementation NotificationServicestatic int lianxunPlay = 1;- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {self.contentHandler = contentHandler;self.bestAttemptContent = [request.content mutableCopy];// Modify the notification content here...self.bestAttemptContent.title = [NSString stringWithFormat:@"%@ [modified]", self.bestAttemptContent.title];self.contentHandler(self.bestAttemptContent);// 方式4,语音合成,使用AudioServicesPlayAlertSoundWithCompletion播放,成功,但是时间最多5秒[self hechengVoice];}
- (void)hechengVoice
{/************************合成音频并播放*****************************/NSMutableArray *audioAssetArray = [[NSMutableArray alloc] init];NSMutableArray *durationArray = [[NSMutableArray alloc] init];[durationArray addObject:@(0)];AVMutableComposition *composition = [AVMutableComposition composition];NSArray *fileNameArray = @[@"daozhang",@"1",@"2",@"3",@"4",@"5",@"6"];CMTime allTime = kCMTimeZero;for (NSInteger i = 0; i < fileNameArray.count; i++) {NSString *auidoPath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@",fileNameArray[i]] ofType:@"m4a"];AVURLAsset *audioAsset = [AVURLAsset assetWithURL:[NSURL fileURLWithPath:auidoPath]];[audioAssetArray addObject:audioAsset];// 音频轨道AVMutableCompositionTrack *audioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:0];// 音频素材轨道AVAssetTrack *audioAssetTrack = [[audioAsset tracksWithMediaType:AVMediaTypeAudio] firstObject];// 音频合并 - 插入音轨文件[audioTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, audioAsset.duration) ofTrack:audioAssetTrack atTime:allTime error:nil];// 更新当前的位置allTime = CMTimeAdd(allTime, audioAsset.duration);}// 合并后的文件导出 - `presetName`要和之后的`session.outputFileType`相对应。AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetAppleM4A];NSString *outPutFilePath = [[self.filePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"xindong.m4a"];if ([[NSFileManager defaultManager] fileExistsAtPath:outPutFilePath]) {[[NSFileManager defaultManager] removeItemAtPath:outPutFilePath error:nil];}// 查看当前session支持的fileType类型NSLog(@"---%@",[session supportedFileTypes]);session.outputURL = [NSURL fileURLWithPath:outPutFilePath];session.outputFileType = AVFileTypeAppleM4A; //与上述的`present`相对应session.shouldOptimizeForNetworkUse = YES;   //优化网络[session exportAsynchronouslyWithCompletionHandler:^{if (session.status == AVAssetExportSessionStatusCompleted) {NSLog(@"合并成功----%@", outPutFilePath);NSURL *url = [NSURL fileURLWithPath:outPutFilePath];static SystemSoundID soundID = 0;AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(url), &soundID);AudioServicesPlayAlertSoundWithCompletion(soundID, ^{NSLog(@"播放完成");});} else {// 其他情况, 具体请看这里`AVAssetExportSessionStatus`.}}];/************************合成音频并播放*****************************/
}

说明:
上面并没有实现 数字转对应音频文件名称数组的过程,直接实现的是合成音频的方法。

坑点:
1、播放的时长仍然受到限制,大概5秒钟。不过如果说播放一个钱数,足够了。
2、合成之后的音频文件用AVAudioPlayer播放是没有声音的


分析:
以上的功能只是针对iOS10以上的系统版本可以,那么iOS10以下的怎么办?可以这么办,不用播报到账多少钱,可以通过定制远程推送的语音,来播报”支付宝,您有一笔到账,请及时查看“之类的,支付宝好像也是这个套路。

每次push之前,先去后台查看当前需要推送的设备的系统版本是啥<这个不难实现>,然后定制推送不同的内容。iOS10以上的就推送钱数,并且不推送sound。
iOS10以下的就推送 "sound"="定制的声音文件名称"。

综上所述,支付宝实现的方式应该是方式二,本地合成音频文件播放的。

还有一个注意点就是,因为打开了下面的这个开关

image.png
再上线的时候可能需要作出一下说明,不然有很大的可能被苹果打回来,最近苹果对这种权限的开启之类的比较严格,如果你没有类似的功能,你还开启了这样的权限,可能被干回来。如果有相关的好的像苹果说明的方法,还请给大家普及一下。

最后献上相关的Demo地址,如果你有更好的建议欢迎留言,如有不正,欢迎来喷。

可以直接用我的Demo进行调试,调试的时候注意修改下bundleId,然后用自己的开发者账号配置一下相关的push证书就可以了

image.png image.png

支付宝
iOS
Apple
单元测试

iOS 模仿支付宝支付到账推送,播报钱数相关推荐

  1. 关于对接保税仓物流系统或支付系统推送报关单的一些琐碎的问题

    最近公司的一个商城的客户,做保税仓发货的功能,该功能需要对接到一些第三方的物流仓报关系统以及支持系统的报关功能,中途碰上了N多个坑,因此记录下来,省的下次忘了 1.由于原本的系统并没有计算税费的功能, ...

  2. ios5.1.1旧版软件下载_苹果iOS 14.1正式版推送 关闭旧版本降级通道

    上周,苹果正式发布了iOS14.1 正式版.而就在今天,苹果则停止了对iOS 14.0.1的验证.这样的举措意味着用户将无法再降级到这一版本. 苹果iOS 14.1正式版推送 关闭旧版本降级通道 iO ...

  3. iOS - AliPay 支付宝支付

    1.支付宝支付申请 支付宝支付官方签约集成指引 支付宝APP支付官方集成指引 蚂蚁金服开放平台 1.1 支付宝 APP 支付申请步骤 APP 支付:APP 支付是商户通过在移动端应用 APP 中集成开 ...

  4. iOS之“支付宝支付”开发流程

    支付宝快捷支付的主要步骤: 先与支付宝签约,获得商户ID(partner)和账号ID(seller); 下载相应的公钥私钥文件(加密签名用); 下载支付宝SDK; 生成订单信息; 调用支付宝客户端,由 ...

  5. iOS开发如何实现消息推送机制

    Push的原理: Push 的工作机制可以简单的概括为下图 图中,Provider是指某个iPhone软件的Push服务器,这篇文章我将使用.net作为Provider. APNS 是Apple Pu ...

  6. IOS安卓友盟消息推送详细配置以及证书更新

    目录 一.友盟消息推动大致流程 二.IOS生成本地应用证书 三.IOS开发者官网申请应用证书 三.友盟官网配置开发者证书 四.安卓应用配置友盟送 五.程序调用更新对应的授权信息 一.友盟消息推动大致流 ...

  7. 推送通知iOS客户端编写实现及推送服务器端编写

    1.iOS客户端编程 推送通知技术在Mac OS X和iOS系统上都可以运行,我们本章主要介绍iOS客户端编程,推送通知的编程比较简单,编程的关键是获得令牌,这是从APNS返回的,然后还有把提交给内容 ...

  8. iOS开发支付宝支付

    iOS支付宝支付(Alipay)详细接入流程以及项目中遇到的问题分析 浏览: 149 发布日期: 2016-10-19  分类: ios  最近在项目中接入了微信支付和支付宝支付,总的来说没有那么坑, ...

  9. ios分屏_华为推送新系统,荣耀9系列全面升级,流畅度比肩苹果iOS

    作为国产手机品牌的代表,华为近几年一直保持着高频率的创新能力,而这不仅体现在手机产品的外观设计.硬件配置方面,软件系统也是创新力最直观的表现,尤其是EMUI10.1系统,在市场上始终保持着极高的热度. ...

最新文章

  1. 使用 Docker 分析高通量测序数据
  2. window下Java的环境变量的配置
  3. [ARM-assembly]-ARM向量浮点指令集 快速参考卡
  4. 【DONE】dbeaver不会用,请教!!!
  5. leetcode--113.路径总和 Ⅱ
  6. python如何避免转义字符_如何解决因转义字符而报错的问题(在使用python导入文件时)...
  7. 让你编程能力秃飞猛进的好习惯
  8. 首届渣打科营编程马拉松赛初赛圆满结束
  9. 不同数据库的自增代码
  10. Atitit.web的自动化操作与信息抓取 attilax总结
  11. 使用@AspectJ注解开发Spring AOP
  12. python学习笔记--python简介
  13. 非常好用的自助建站程序整站源码 内置几十种站
  14. 常用RGB颜色查询对照表及感情色
  15. 数据防泄露解决方案-智能制造
  16. 【测试】linux tc命令|Linux模拟网络延迟、丢包等|traffic control(流量控制)
  17. DSP CCS12.00 芯片:TMS320F28335 PWM 的设计
  18. java 类型转换
  19. 基于VB图书管理系统的设计与实现
  20. 【面向学渣编程】囚犯问题(十分详解,含表格,适合新手)

热门文章

  1. java开发工具对比eclipse·myeclipse·idea
  2. java内存分配--引用
  3. Hadoop 生态系统
  4. Perl时间处理函数
  5. C# 的三种序列化方法
  6. ASP.NET 3.5揭秘-读书笔记1
  7. Asp.Net开发架构设计(二)
  8. CentOS Linux内核升级全过程
  9. 如何用C#动态编译、执行代码
  10. 通过WMI获得硬盘和CPU的物理序列号(VB.net)