1. 程式人生 > >iOS 退款(或訂單)推送訊息語音播報

iOS 退款(或訂單)推送訊息語音播報

近期無知經理突然提出一個蛋疼的需求,並表示這是“客戶和市場強制要求”做的。。。沒辦法,只能硬著頭皮上了。

之前採用的是靜默推送+普通推送,而且網上大部分資料也預設使用的是靜默推送方式。據我所知,該方案有一定的缺陷:

1.部分機器收不到語音播報;

2.若需要在後臺或鎖屏狀態下播報語音時,上架會遇到"Audio,AirPlay,and Picture in Picture"和"Background fetch"等問題稽核被拒。通過查閱網上的資料,我改用iOS 10新的API推送擴充套件(UNNotificationServiceExtension),三方SDK使用極光,關於整合方式就不多說了,詳見極光官方文件

這種方案的特點是:節省大量程式碼,上架簡單,伺服器只需要推一條訊息,但iOS 10以上"mutable-content = 1"必傳,否則程式不走這個擴充套件的Target。

實現原理

  • iOS 10以上採用推送擴充套件(極光必傳mutable-content,iOS 10以下不需要)處理,使用iOS原生API AVSpeechSynthesizer實現文字合成語音。



  • iOS10以下采用固定音訊檔案播放,比如“您有一條新訂單,請及時處理!”。

    相關程式碼

    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
        
        [JPUSHService handleRemoteNotification:userInfo];
        completionHandler(UIBackgroundFetchResultNewData);
        
        //  iOS 10之前前臺沒有通知欄
        if ([UIDevice currentDevice].systemVersion.floatValue < 10.0 && [UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
           //  iOS 10以下 極光前臺不展示訊息欄,此處為自定義內容
           [EBBannerView showWithContent:@"交易結果通知"];
                
           //  獲取共享域的偏好設定(可百度“多target資料共享”)
           NSUserDefaults *userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.xxx"];
           BOOL canSound = [userDefault boolForKey:@"voice"];
           if (canSound) {
               //  播放refund.wav或collection.wav固定音訊檔案
               if ([refund condition]) {
                   [self playMusic:@"refund" type:@"wav"];
               } else {
                   [self playMusic:@"collection" type:@"wav"];
               }
           }
        }
    }
    
    //  播放音訊檔案
    - (void)playMusic:(NSString *)name type:(NSString *)type {
        //得到音效檔案的地址
        NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:name ofType:type];
        //將地址字串轉換成url
        NSURL *soundURL = [NSURL fileURLWithPath:soundFilePath];
        //生成系統音效id
        AudioServicesCreateSystemSoundID((__bridge CFURLRef)soundURL, &_soundFileObject);
        //播放系統音效
        AudioServicesPlaySystemSound(_soundFileObject);
    }

    • iOS 10及以上:

    - (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
        self.contentHandler = contentHandler;
        self.bestAttemptContent = [request.content mutableCopy];
        //  iOS 10在有語音播報的情況下 可遮蔽系統提示音,也可根據需求來
        self.bestAttemptContent.sound = nil;
        
        // Modify the notification content here...    
        //  獲取共享域的偏好設定
        NSUserDefaults *userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group. xxx"];
        
        //  解析推送自定義引數userInfo
        NSDictionary *userInfo = [self dictionaryWithUserInfo:self.bestAttemptContent.userInfo];
        
        BOOL canSound = [userDefault boolForKey:@"voice"];
        NSString *voiceString = nil;
        if (canSound) {
            if ([refund condition]) {
                voiceString = [NSString stringWithFormat:@"退款%@元!", userInfo[@"money"]];
            } else {
                voiceString = [NSString stringWithFormat:@"收款%@元!", userInfo[@"money"]];
            }
        }
        //  語音合成
        [self syntheticVoice:voiceString];    
        self.contentHandler(self.bestAttemptContent);
    }

    - (void)syntheticVoice:(NSString *)string {
        
        //  語音合成
        self.synthesizer = [[AVSpeechSynthesizer alloc] init];
        AVSpeechUtterance *speechUtterance = [AVSpeechUtterance speechUtteranceWithString:string];
        //設定語言類別(不能被識別,返回值為nil)
        speechUtterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"];
        //設定語速快慢
        speechUtterance.rate = 0.55;
        //語音合成器會生成音訊 
        [self.synthesizer speakUtterance:speechUtterance];
    }
    君凱商聯網-iOS-字唐名僧