iOS语音播报功能

如果要在App内简单地实现语音播报功能,使用AVSpeechSynthesizer就可以实现:

1
2
3
4
5
6
7
AVSpeechSynthesizer *speechSynthesizer = [[AVSpeechSynthesizer alloc]init];
AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:@"语音播报的内容"];
utterance.voice = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"];
CGFloat rate = 0.5;
utterance.rate = rate;
utterance.preUtteranceDelay = 0.0;
[speechSynthesizer speakUtterance:utterance];

值得注意的是,在不同的iOS版本的设备上语音速度有所不同。正常的语速设置:

1
2
3
4
5
6
CGFloat rate = 0.5;//iOS10及以上版本默认0.5的速度基本正常
if (IOS_VERSION >= 9.0 && IOS_VERSION < 10.0) {
rate = 0.52;//iOS9上速度略慢
}else if (IOS_VERSION >= 8.0 && IOS_VERSION < 9.0){
rate = 0.15;//iOS8的语音播报速度非常快
}

语音播报最常见的应用是后台播报,比如支付宝、微信等收到转账时会有语音提醒到账。很容易想到使用APNs来推送消息,收到推送后语音播报推送内容。在后台语音的功能实现上,可能会考虑开启background modes中的Audio and AirPlay模式。开启后台audio模式的确可以对收到的语音实时播报,但你要是去上架,就会被拒。我们来看看苹果官方对于Audio and AirPlay模式的功能描述:

The app plays audible content to the user or records audio while in the background. (This content includes streaming audio or video content using AirPlay.)

The user must grant permission for apps to use the microphone prior to the first use.

由此我们可以看出,开启后台语音必须满足后台持续的语音流,比如音乐播放、录音等。而我们要实现的后台语音播报功能则是在不定时收到推送时才语音播报。这个方法只能pass。

实现方式:

iOS10以前的只能实现在app运行中收到消息时播报,iOS10以后可以通过Notification Service Extension来实现。

![add extension](/images/add extension.png)

在生成的.m文件的-(void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler方法中对消息内容进行播报即可。

添加Notification Service Extension之后可能出现的问题及解决方法:
  1. 添加了notification extension之后,提示:

    extension证书报错

    即使证书设置的完全相同,仍然报错。

    解决方法:在钥匙串访问里找到Apple Worldwide Developer Relations Certification Authority证书,修改始终信任为系统默认,重新编译即可。

  2. 最低版本支持iOS8.0的项目,添加了支持iOS10以上的extension(Notification Service Extension)之后,无法运行在iOS8的手机上:

    *This app contains an app extension that specifies an extension point identifier that is not supported on this version of iOS for the value of the NSExtensionPointIdentifier key in its Info.plist.

    报出下面的弹窗:

    Extension在ios8安装错误

    解决方法:

    extension在ios8安装错误解决方法

    修改general里面的deployment target为10.0即可。