iOS-后臺語音播報

公司要求需要做一個類似支付寶的收款的語音播報功能,研究了一天才完成,記錄下來

寫在前面

語音播報功能的實現必須是推送語音合成,選擇的推送是極光推送,本文最終實現的效果即使APP被殺死也可以進行語音播報

實現

  1. 配置推送證書,極光文檔里面有,把極光推送集成進去就不說了

  2. 語音合成我用的是系統的方法,不過語音死板不好聽,但是使用很簡單,3行代碼就可以,建議使用其他的SDK

    AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:@"成功集成語音播報"];
     
    AVSpeechSynthesizer *synth = [[AVSpeechSynthesizer alloc] init];
     
    [synth speakUtterance:utterance];
    
  3. 在收到通知的時候使用上面的3行代碼就可以進行語音播報,但是只限于APP前臺運行,當后臺運行的時候語音播報便不可以了,此時需要加入下面代碼讓語音播報可以在后臺運行,但是殺死的情況下不能播報,殺死重新啟動返回后臺也不可以播報. 我是在AppDelegate里面寫入這個方法的

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
    

    把下面的代碼寫入進去

    NSError *error = NULL;
     
    AVAudioSession *session = [AVAudioSession sharedInstance];
     
    [session setCategory:AVAudioSessionCategoryPlayback error:&error];
     
    if(error) {
        // Do some error handling
         
    }
     
    [session setActive:YES error:&error];
     
    if (error) {
        // Do some error handling
    }
     
    // 讓app支持接受遠程控制事件
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    
  4. 讓語音播報在后臺也可以進行的話就需要在

    // 在AppDelegate定義屬性
    @property (nonatomic, unsafe_unretained) UIBackgroundTaskIdentifier backgroundTaskIdentifier;
    
    - (void)applicationWillResignActive:(UIApplication *)application;
    

    里面加入以下的方法

     - (void)applicationWillResignActive:(UIApplication *)application {
    
     // 開啟后臺處理多媒體事件
    
     [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    
     AVAudioSession *session=[AVAudioSession sharedInstance];
    
     [session setActive:YES error:nil];
    
     // 后臺播放
    
     [session setCategory:AVAudioSessionCategoryPlayback error:nil];
    
     // 這樣做,可以在按home鍵進入后臺后 ,播放一段時間,幾分鐘吧。但是不能持續播放網絡歌曲,若需要持續播放網絡歌曲,還需要申請后臺任務id,具體做法是:
    
     _backgroundTaskIdentifier=[AppDelegate backgroundPlayerID:_backgroundTaskIdentifier];
    
     // 其中的_bgTaskId是后臺任務UIBackgroundTaskIdentifier _bgTaskId;
     
     }
     //實現一下backgroundPlayerID:這個方法:
     
     +(UIBackgroundTaskIdentifier)backgroundPlayerID:(UIBackgroundTaskIdentifier)backTaskId{
     
     //設置并激活音頻會話類別
    
     AVAudioSession *session=[AVAudioSession sharedInstance];
    
     [session setCategory:AVAudioSessionCategoryPlayback error:nil];
    
     [session setActive:YES error:nil];
    
     //允許應用程序接收遠程控制
    
     [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    
     //設置后臺任務ID
    
     UIBackgroundTaskIdentifier newTaskId=UIBackgroundTaskInvalid;
    
     newTaskId=[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
    
     if(newTaskId!=UIBackgroundTaskInvalid&&backTaskId!=UIBackgroundTaskInvalid){
    
     [[UIApplication sharedApplication] endBackgroundTask:backTaskId];
    
     }
    
     return newTaskId;
     
    }
    
  5. 到這里就可以進行后臺播報了,但是注意 到這一步只有在程序沒有被殺死的情況下才可以播報, 殺死之后是不能播報的, 所有我們還要進行處理,這時需要使用 UNNotificationServiceExtension.

    • 創建 UNNotificationServiceExtension

      填寫文件名,邊創建好了

      WX20170623-102242@2x.png
  • NotificationService.m 里面有一個方法

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

    此時把語音播報寫進去就可以了

     - (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];
    
         NSString *content = request.content.userInfo[@"aps"][@"alert"][@"body"];
    
         AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:content];
    
         AVSpeechSynthesizer *synth = [[AVSpeechSynthesizer alloc] init];
    
         [synth speakUtterance:utterance];
    
         self.contentHandler(self.bestAttemptContent);
    }
    
  • 認為到這里就完成了?,NO!在發送推送的時候還需要在極光推送服務里面配置一下

    WX20170623-103137.png

到這一步的時候,后臺播報就可以執行了, 但是 此播報服務只能在 iOS10 系統之后才可以進行, 如果想適配iOS9之前的只能做一個固定的音頻文件放到項目里面,比如支付寶的的到賬提醒, 然后在推送的時候

WX20170623-103724.png

這時候就可以完美播放音頻文件了, 提醒: 如果不需要動態的語音播放, 直接可以使用這個方法,不需要配置 UNNotificationServiceExtension 和后臺播放了,因為這個方法是系統認為推送的提示音

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容