ARKit应用中AVSpeechSynthesizer报‘Unable to list voice folder’错误,移类外仍无效求解决及替代
解决AVSpeechSynthesizer的“Unable to list voice folder”错误及替代方案
一、排查现有代码的潜在问题
- 调整合成器声明位置:避免全局声明合成器,把它移到ViewController类内部作为实例属性,防止AVFoundation未完全初始化时创建实例:
import AVFoundation class YourViewController: UIViewController { // 类内部声明合成器实例 let synthesizer = AVSpeechSynthesizer() func testSpeak() { let utterance = AVSpeechUtterance(string: "screen has been tapped") // 先验证指定语言语音是否可用,避免强行赋值触发错误 if let voice = AVSpeechSynthesisVoice(language: "en-US") { utterance.voice = voice } synthesizer.speak(utterance) } }
- 检查设备可用语音:有些设备可能未预装目标语言语音,添加代码查看可用资源:
// 在testSpeak函数内添加,打印所有可用语音 let availableVoices = AVSpeechSynthesisVoice.speechVoices() availableVoices.forEach { voice in print("语音名称:\(voice.name),语言代码:\(voice.language)") }
- 确保主线程调用:如果在ARKit的后台回调(如渲染回调)中调用朗读功能,需切换到主线程执行:
DispatchQueue.main.async { self.testSpeak() }
二、替代方案
如果上述方法无效,推荐两种适合少量文本朗读的轻量方案:
- 使用无障碍播报API:直接调用系统无障碍播报功能,无需手动管理合成器:
import UIKit func testSpeak() { UIAccessibility.post(notification: .announcement, argument: "screen has been tapped") }
- 预录制音频播放:若文本固定,提前录制对应音频文件添加到项目,用AVAudioPlayer播放:
import AVFoundation class YourViewController: UIViewController { var audioPlayer: AVAudioPlayer? func playPreRecordedAudio() { guard let audioURL = Bundle.main.url(forResource: "tap_prompt", withExtension: "mp3") else { return } do { audioPlayer = try AVAudioPlayer(contentsOf: audioURL) audioPlayer?.play() } catch { print("音频播放失败:\(error.localizedDescription)") } } }
内容的提问来源于stack exchange,提问作者sl11
相关产品推荐
相关产品推荐

