Mac Catalyst应用中AVSpeechSynthesizer无法工作 直接触发取消回调
Mac Catalyst AVSpeechSynthesizer 播报被取消适配方案
以下是经过验证的可解决该问题的修改点:
- 调整AVSpeechSynthesizer实例持有逻辑
不要每次播报都重新创建AVSpeechSynthesizer实例,将其设置为当前类的strong修饰的全局属性,保证实例在播报完成前不会被提前释放。Mac Catalyst对该实例的生命周期敏感度远高于iOS,局部实例或反复创建销毁都会直接触发didCancelSpeechUtterance回调。 - 开启沙盒音频权限
打开项目的Signing & Capabilities tab,找到App Sandbox配置,勾选Audio Input权限,Mac沙盒限制下未开启音频相关权限会直接拦截语音合成请求。 - 显式指定语音实例
Mac端不会默认加载所有语言的语音包,不要使用默认语音配置,需显式指定对应语言的AVSpeechSynthesisVoice实例,增加可用性判断:AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:text]; // 显式指定和播报文本匹配的语言语音,例如中文使用zh-CN AVSpeechSynthesisVoice *targetVoice = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"]; if (!targetVoice) { // 兜底取系统第一个可用语音 targetVoice = [AVSpeechSynthesisVoice speechVoices].firstObject; } if (targetVoice) { utterance.voice = targetVoice; } - 调整停止播报逻辑
去掉初始化synthesizer之后立刻调用stopSpeakingAtBoundary的逻辑,修改为仅当已有播报任务执行时才调用停止方法,避免新创建的实例未就绪时调用停止接口导致后续播报任务被标记为取消:// 初始化前先处理已有播报任务 if (self.synthesizer && [self.synthesizer isSpeaking]) { [self.synthesizer stopSpeakingAtBoundary:AVSpeechBoundaryImmediate]; } // 再初始化/使用已有实例 if (!self.synthesizer) { self.synthesizer = [[AVSpeechSynthesizer alloc]init]; self.synthesizer.delegate = self; }
内容的提问来源于stack exchange,提问作者NSGodMode
相关产品推荐
相关产品推荐

