語(yǔ)音播報(bào)功能的實(shí)現(xiàn)必須是推送加語(yǔ)音合成,選擇的推送是極光推送,本文最終實(shí)現(xiàn)的效果即使APP被殺死也可以進(jìn)行語(yǔ)音播報(bào)
配置推送證書,極光文檔里面有,把極光推送集成進(jìn)去就不說(shuō)了
語(yǔ)音合成我用的是系統(tǒng)的方法,不過(guò)語(yǔ)音死板不好聽(tīng),但是使用很簡(jiǎn)單,3行代碼就可以,建議使用其他的SDK
AVSpeechUtterance*utterance = [AVSpeechUtterancespeechUtteranceWithString:@"成功集成語(yǔ)音播報(bào)"];
AVSpeechSynthesizer*synth = [[AVSpeechSynthesizeralloc] init];
[synth speakUtterance:utterance];
在收到通知的時(shí)候使用上面的3行代碼就可以進(jìn)行語(yǔ)音播報(bào),但是只限于APP前臺(tái)運(yùn)行,當(dāng)后臺(tái)運(yùn)行的時(shí)候語(yǔ)音播報(bào)便不可以了,此時(shí)需要加入下面代碼讓語(yǔ)音播報(bào)可以在后臺(tái)運(yùn)行,但是殺死的情況下不能播報(bào),殺死重新啟動(dòng)返回后臺(tái)也不可以播報(bào). 我是在AppDelegate里面寫入這個(gè)方法的
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions;
把下面的代碼寫入進(jìn)去
NSError*error =NULL;
AVAudioSession*session = [AVAudioSessionsharedInstance];
[session setCategory:AVAudioSessionCategoryPlaybackerror:&error];
if(error) {
// Do some error handling
}
[session setActive:YESerror:&error];
if(error) {
// Do some error handling
}
// 讓app支持接受遠(yuǎn)程控制事件
[[UIApplicationsharedApplication] beginReceivingRemoteControlEvents];
讓語(yǔ)音播報(bào)在后臺(tái)也可以進(jìn)行的話就需要在
// 在AppDelegate定義屬性
@property(nonatomic,unsafe_unretained)UIBackgroundTaskIdentifierbackgroundTaskIdentifier;
- (void)applicationWillResignActive:(UIApplication*)application;
里面加入以下的方法
- (void)applicationWillResignActive:(UIApplication*)application {
// 開(kāi)啟后臺(tái)處理多媒體事件
[[UIApplicationsharedApplication] beginReceivingRemoteControlEvents];
AVAudioSession*session=[AVAudioSessionsharedInstance];
[session setActive:YESerror:nil];
// 后臺(tái)播放
[session setCategory:AVAudioSessionCategoryPlaybackerror:nil];
// 這樣做,可以在按home鍵進(jìn)入后臺(tái)后 ,播放一段時(shí)間,幾分鐘吧。但是不能持續(xù)播放網(wǎng)絡(luò)歌曲,若需要持續(xù)播放網(wǎng)絡(luò)歌曲,還需要申請(qǐng)后臺(tái)任務(wù)id,具體做法是:
_backgroundTaskIdentifier=[AppDelegate backgroundPlayerID:_backgroundTaskIdentifier];
// 其中的_bgTaskId是后臺(tái)任務(wù)UIBackgroundTaskIdentifier _bgTaskId;
}
//實(shí)現(xiàn)一下backgroundPlayerID:這個(gè)方法:
+(UIBackgroundTaskIdentifier)backgroundPlayerID:(UIBackgroundTaskIdentifier)backTaskId{
//設(shè)置并激活音頻會(huì)話類別
AVAudioSession*session=[AVAudioSessionsharedInstance];
[session setCategory:AVAudioSessionCategoryPlaybackerror:nil];
[session setActive:YESerror:nil];
//允許應(yīng)用程序接收遠(yuǎn)程控制
[[UIApplicationsharedApplication] beginReceivingRemoteControlEvents];
//設(shè)置后臺(tái)任務(wù)ID
UIBackgroundTaskIdentifiernewTaskId=UIBackgroundTaskInvalid;
newTaskId=[[UIApplicationsharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
if(newTaskId!=UIBackgroundTaskInvalid&&backTaskId!=UIBackgroundTaskInvalid){
[[UIApplicationsharedApplication] endBackgroundTask:backTaskId];
}
returnnewTaskId;
}
到這里就可以進(jìn)行后臺(tái)播報(bào)了,但是注意到這一步只有在程序沒(méi)有被殺死的情況下才可以播報(bào), 殺死之后是不能播報(bào)的, 所有我們還要進(jìn)行處理,這時(shí)需要使用 UNNotificationServiceExtension.
創(chuàng)建 UNNotificationServiceExtension

填寫文件名,邊創(chuàng)建好了

在NotificationService.m里面有一個(gè)方法
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void(^)(UNNotificationContent * _Nonnull))contentHandler;
此時(shí)把語(yǔ)音播報(bào)寫進(jìn)去就可以了
- (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 = [NSStringstringWithFormat:@"%@ [modified]",self.bestAttemptContent.title];
NSString*content = request.content.userInfo[@"aps"][@"alert"][@"body"];
AVSpeechUtterance*utterance = [AVSpeechUtterancespeechUtteranceWithString:content];
AVSpeechSynthesizer*synth = [[AVSpeechSynthesizeralloc] init];
[synth speakUtterance:utterance];
self.contentHandler(self.bestAttemptContent);
}
認(rèn)為到這里就完成了?,NO!在發(fā)送推送的時(shí)候還需要在極光推送服務(wù)里面配置一下

到這一步的時(shí)候,后臺(tái)播報(bào)就可以執(zhí)行了, 但是此播報(bào)服務(wù)只能在 iOS10 系統(tǒng)之后才可以進(jìn)行, 如果想適配iOS9之前的只能做一個(gè)固定的音頻文件放到項(xiàng)目里面,比如支付寶的的到賬提醒, 然后在推送的時(shí)候

這時(shí)候就可以完美播放音頻文件了, 提醒:如果不需要?jiǎng)討B(tài)的語(yǔ)音播放, 直接可以使用這個(gè)方法,不需要配置 UNNotificationServiceExtension 和后臺(tái)播放了,因?yàn)檫@個(gè)方法是系統(tǒng)認(rèn)為推送的提示音