iOS 模仿支付寶支付到賬推送,播報錢數
最近申請了支付寶的二維碼收錢碼,其中支付寶有這麼一個功能,就是,別人掃描你的二維碼給你轉賬之後,收到錢會有一條語音推送,”支付寶到賬 1000萬“之類的推送訊息,不管你的支付寶app有沒有被殺死。
只要你的遠端推送開著,並且支付寶的"二維碼收錢到賬語音提醒",都開啟著,就可以收到。
開啟方式:支付寶點選右上角設定-通用-新訊息通知,開啟到賬提醒即可。
image.png
並且別人給你轉多少錢就會播報到賬多少錢。
探索實現一下。
當前有兩種方案實現了上面描述的場景。
必備條件
上面的描述場景只有在iOS10以上版本才可以,因為必須要基於Notification Servivice Extension
image.png
如果對Notification Servivice Extension不是很熟悉的,建議先了解一下
iOS10 推送extension之 Service Extension你玩過了嗎?
實現方式
1、ServiceExtension中收到推送之後,用AVSpeechSynthesisVoice相關類,直接把推送過來需要播報相關的文字轉化成語音播報
2、ServiceExtension中收到推送之後,將要播報的數字,找到對應的單個音訊,排序,用拼接音訊的方式<通過推送過來的文字去查詢相關的音訊,然後拼接成一個音訊>,然後使用AudioServicesCreateSystemSoundID播放
在介紹相關方式之前,先介紹一個測試工具
SmartPush
使用方式也很簡單,應該一看就懂
正式進入主題
方式一
@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;
}
// 建立嗓音,指定嗓音不存在則返回nil
AVSpeechSynthesisVoice *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、收到推送了,但是沒有播報語音,檢查一下這裡
3、播放的聲音時間長度,經過測試最多是5秒鐘,這裡應該是蘋果做了限制,拿上面的推送內容舉例子"body":"世上只有媽媽好,有媽的孩子像塊寶。投進媽媽的懷抱,幸福哪裡找。沒媽的孩子像根草"
,最多也就是播放到世上只有媽媽好,有媽的孩子像塊寶。投進媽媽的懷抱
方式二
經過對比,支付寶播放的聲音明顯比系統方法文字轉語音播放的好聽,一聽就是小姑娘錄得。要麼就是自己整合了一套文字轉語音的東西。
首先嚐試使用科大訊飛來實現,結果失敗了。
然後嘗試的是語音合成的方式來播放
比如提前先錄好 以下可能播報的內容
支付寶到賬、 0、 1、 2、 3、 4、 5、 6、 7、 8、 9、 十、 百、 千、 萬、 十萬、 百萬、 千萬、 億、 元 等等
這樣的幾種錄音,然後用相關的名字命名好<相關的規則自己命名就好>。
比如push過來的是內容是 10010
,那麼轉化成的錄音檔名稱的陣列就是
@[@"支付寶到賬",@"1",@"萬",@"0",@"1",@"十",@"元"]
然後找到這幾個檔案,然後按照順序拼接成一個語音檔案進行播放
程式碼演示:
@implementation NotificationService
static 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證書就可以了
本文轉自:https://blog.csdn.net/qq_34047841/article/details/78232438
相關文章
- Java 支付寶支付,退款,單筆轉賬到支付寶賬戶(支付寶訂單退款)Java
- 支付寶記賬功能怎麼用?支付寶記賬功能的使用方法
- java實現沙箱測試環境支付寶支付(demo)和整合微信支付和支付寶支付到springmvc+spring+mybatis環境全過程(支付寶和微信支付、附原始碼)JavaSpringMVCMyBatis原始碼
- iOS使用Stripe整合支付寶Alipay支付iOS
- Laravel實現支付寶分賬Laravel
- 2023支付寶五一消費洞察
- php 支付寶 SDK 單筆轉賬PHP
- 支付寶實時到賬的MVC示例MVC
- 小米手環3繫結支付寶免密支付教程 小米手環3支援支付寶免密支付嗎?
- Thinkphp5.0支付寶支付擴充套件庫類庫大全PHP套件
- 支付寶:2020老年人數字生活報告
- 支付寶-API介面解析-轉賬到銀行API
- yansongda 支付寶商家轉賬給使用者
- 支付寶轉賬介面HTTP/2 stream 0 was not closed close cleanly報錯解決HTTP
- 小米手環3怎麼設定支付寶免密支付?小米手環3支付寶免密支付設定新增教程
- 玩轉 iOS 開發:整合 AliPay – 支付寶iOS
- iOS12 beta2支付寶閃退、卡死打不開的解決辦法iOS
- SpringBoot(二)整合支付寶 - 電腦網站支付和查詢賬單Spring Boot網站
- 支付寶免籤,個人支付寶,自動轉賬,自動提現到銀行卡,自動銀行卡轉賬
- 支付寶支付
- 對iOS端支付寶和微信支付程式碼進行整合iOS
- 支付寶,微信,充值遇到的到賬延遲
- 2022年支付行業研究報告行業
- 利用抖音Cookie充值介面提取支付連結,個人調起原生微信h5支付寶h5支付CookieH5
- 支付寶沾福氣卡是什麼?2019支付寶沾福氣卡獲得和使用方法
- 微信支付,支付寶支付
- 免SDK實現微信/支付寶轉賬打賞功能
- 支付寶介面的數字簽名
- 凱捷:2021年支付趨勢報告
- 建立數字錢包(一)賬號生成
- 支付寶 二維碼/轉賬碼/生成方式,突破二維碼生成數量的限制
- iOS 本地推送iOS
- 關於微信支付,支付寶支付
- 餘額寶90後攢錢報告
- 支付寶alipay移動支付
- 支付寶、微信支付(.NET)
- vue-仿支付寶支付Vue
- Django呼叫支付寶支付介面Django