美文网首页iOS程序员的业余沙龙
iOS 后台金额播报(类似支付宝 收款金额播报)

iOS 后台金额播报(类似支付宝 收款金额播报)

作者: DaDaCool | 来源:发表于2017-11-02 16:34 被阅读1426次

    由于现在二维码支付越来越流行。越来越多的小伙伴参与到聚合支付的行业中。那在app的开发中,金额播报这个功能肯定是必要的一项了!

    下面直接进入主题

    金额播报的情形(主流app工具如“支付宝”“收钱吧”)

    1、iOS 10以下的设备收到钱之后不管App是杀死还是进入后台状态都会播报”xxxx收款成功”一句固定的语音

    2、iOS 10以上的设备,收到钱之后,不管APP是杀死还是压入后台状态,在收到转账的时候,会播报”xxx到账 xxx 元”


    实现以上功能注意的点:

    iOS 10以上和iOS10以下设备,实现方式不一样

    1.iOS10以前的收款播报是在后台或者app被杀死的时候,播放一个固定的声音,可以借助远程推送定制铃声的功能来实现,只要在本地添加一段提前录制好的语音,并且在推送内容的时候将sound字段,修改成语音的名称即可。(ios 10 之前也可以有另类的方法做到,后台金额播报,后面会有介绍)

    2.iOS10以后,无论是app在后台,或者没有开启,都可以进行具体的播报金额. 用到的是iOS 10的推送扩展( Notification Extension)

    推荐的语音播报的两种方式

    1.科大讯飞的语音合成  (有两个GG 两个MM的声音可以选)                        ->      科大讯飞语音合成

    2.系统语音合成         -> 系统语音播报

    #import <AVFoundation/AVFoundation.h>

    AVSpeechUtterance * aVSpeechUtterance = [[AVSpeechUtterance alloc] initWithString:@"想说啥就说啥"];

    aVSpeechUtterance.rate = AVSpeechUtteranceDefaultSpeechRate; 

    aVSpeechUtterance.voice =[AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"]; 

    [self.aVSpeechSynthesizer speakUtterance:aVSpeechUtterance]; 

    下面我们一步一步来完成这个功能的实现

    iOS 10以上处理方法 Notification Extension  

    原理如下,想要深入研究的可以看看    NotificationServiceExtension

    1.

    生成以下的文件

    点开的.m文件

    #import "NotificationService.h"

    #import@interface NotificationService ()

    @property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);

    @property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;

    @property (nonatomic, strong) AVSpeechSynthesizer *aVSpeechSynthesizer;

    @end

    @implementation NotificationService

    - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {

    self.contentHandler = contentHandler;

    self.bestAttemptContent = [request.content mutableCopy];

    self.bestAttemptContent.title = [NSString stringWithFormat:@"%@",request.content.body];

    self.bestAttemptContent.subtitle = @"";

    self.bestAttemptContent.body = @"";

    self.aVSpeechSynthesizer = [[AVSpeechSynthesizer alloc] init];

    //request 可以获取所有推送信息,里面可以取得播报内容

    AVSpeechUtterance * aVSpeechUtterance = [[AVSpeechUtterance alloc] initWithString:@"这里放入播报的声音文字就行了"];

    aVSpeechUtterance.rate = AVSpeechUtteranceDefaultSpeechRate;   

    aVSpeechUtterance.voice =[AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"];   

    [self.aVSpeechSynthesizer speakUtterance:aVSpeechUtterance];

    self.contentHandler(self.bestAttemptContent);

    }

    你以为这就结束了吗???NO,NO,NO 下面很关键

    1. 后端给你推送过来的json 必须添加     "mutable-content":1     (后台一直引用不出来这个参数方法,请让他升级推送!)

    2.播放的语音时长最好不要超过30秒   (我也不信谁能播放30秒)

    3.iOS10以下推送的sound 有值,想要iOS10 以上没有推送声音 可以设置 self.bestAttemptContent.sound = nil;

    4.断点调试的时候,跑正确的target

    iOS10以上推送金额播报大致就是这样的一个流程。本文章也只提供一个大致的思路和实现方法。具体的细节处理 可以自己去琢磨。比如支付宝的金额播报,他们的钱的单位和0 - 9 的数字都是固定语音,大概就是将推送获取的金额,然后音频拼接起来,有兴趣的可以自己研究。

    下面简单说说iOS10以下的后台金额播报

    首先,未开启app的话不可能详细的金额播报啦!!

    方式一 ,app进入后台后 就进行无声的音乐播放,每三分钟拨一次,保证app一直后台活跃,并且  

    然后接到推送后,就可以播报

    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(nonnull void (^)(UIBackgroundFetchResult))completionHandler {

    //回调

    NSLog(@"Received remote notification with userInfo %@", userInfo);

    completionHandler(UIBackgroundFetchResultNewData);

    //语音播报

    AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:@“userinfo有你要读的东西”];

    AVSpeechSynthesizer *synth = [[AVSpeechSynthesizer alloc] init];

    [synth speakUtterance:utterance];

    }


    重点:

    1."content-avilable" =1   后端必须传这个字段。 (静默推送)    

    2.

    勾选后,可能会被苹果拒绝!你可以上传一段你使用后台播放的用途!这个通过率大概30% ,看运气!

    如果你有更好的建议,想法,或者疑问,欢迎留言!

    相关文章

      网友评论

      • 道无为_0092:楼主你好,我用系统的在收到通知时可以播放,但是用科大讯飞的就无法播放
      • 徐的啦啦啦:大神,我按照你的要求来操作,但 target中并没有走断点呀
        alert和mutable-content = true都是有的
        徐的啦啦啦:@DaDaCool 请问运行推送扩张类的方法是啥呢?
        徐的啦啦啦:@DaDaCool 大神这是我推送的信息,
        "_j_business" = 1;
        "_j_msgid" = 2194558857;
        "_j_uid" = 6801416771;
        aps = {
        alert = "\U7528\U62371\U7684\U62a5\U9500\U9700\U8981\U60a8\U5ba1\U6279";
        badge = 33;
        "mutable-content" = 1;
        sound = "money.wav";
        };
        expenseid = 84;
        "msg_content" = 1;
        DaDaCool:target选对了嘛 ?有没有运行推送扩张类的方法?
      • saman0:你的讯飞怎么调用的
        saman0:@DaDaCool 我也是用的系统语音
        saman0:@DaDaCool 我试过根本不行,所以看看有没有同学弄好
        DaDaCool:你是想说推送扩展.m文件引用不了第三方库吧。我是用系统的播报。你可以自己封装讯飞播报语音类。然后直接调用自己写的那个类就行了。
      • 谁叫我嘉Hong:我按照方法写了可是推送一直不走NotificationService里面的代理 。。要怎么调试啊? 我有选择target跑了
        DaDaCool:@谁叫我嘉Hong "mutable-content":1 后端推送aps里面加这个没有
        谁叫我嘉Hong:@DaDaCool 主要是代理方法都不走
        DaDaCool:@谁叫我嘉Hong 那没有调试的状态下的播报有实现吗?
      • 歌白尼:楼主你好,如果项目新增了Notification Extension target,无法在iOS10以下的设备安装的,提示无法安装,只有在iOS10以上的设备才可以。想问下兼容10以下系统有没方案呢
        DaDaCool:新增了Notification Extension target 也不会导致iOS10以上的设备才可以装哦,我这边试过iOS9的手机,是没有问题的。应该是别的问题导致的哈
      • jiangxuntong:你好关于该功能 我们公司要求有关闭语音播报的功能 但在NotificationService 文件中无法获取偏好设置 我也尝试写入到沙盒中 也是读取的内容不正确 如何实现关闭语音播报这个功能呢!望指点
        单腿行走的大象:兄弟 你是怎么解决的 我在沙盒中保存合成的语音文件 保存不成功啊
        DaDaCool:不好意思,最近一直在忙,现在才看到。 关闭语音播报的话,这边可以在app里面设置一个按钮,打开和关闭都调用后端的接口,让后端记录。推送的时候把那个 是否打开关闭的状态返新增个参数推给你就行了。然后你在NotificationService中判断是否播报。 :grin: 别的设置方法我现在还不知道
      • hY_Ramos:你好,怎么在NotificationService.m中调用项目中的第三方,引入不了第三方库,比如阿里云的TTS语音播放功能
        雯小懒:@DaDaCool 而且我用系统的播报也有问题,但是读的时候断断续续,或者读不完,请问怎么解决呢?
        雯小懒:@DaDaCool 你好,我这边也是自己封装的类,我是用的讯飞,引入后发现我的类里面不能引入讯飞了,请问具体怎么引入呢?
        DaDaCool:@hY_Ramos 不好意思,最近忙,刚看到回复,我这边NotificationService.m中用第三方的话,我都是自己封装写的类。然后直接调用自己写的那个类就行了。:sunglasses:
      • 有缘人2830:写的很不错,遇到问题也帮着解决。非常感谢!
      • 3d4d627deaa4:是这样的

      本文标题:iOS 后台金额播报(类似支付宝 收款金额播报)

      本文链接:https://www.haomeiwen.com/subject/fbnuhttx.html