能否通过编程方式下载iPhone未预装的AVSpeechSynthesisVoice?
如何在iOS应用内编程下载AVSpeechSynthesisVoice?
可以实现,iOS 13及以上系统提供了官方API支持直接在应用内触发语音包下载,无需跳转系统设置。核心是使用AVSpeechSynthesisVoice的prefetchVoice(withIdentifier:completionHandler:)方法,以下是具体实现方案:
实现步骤
- 先判断系统版本是否在iOS 13及以上,避免低版本系统调用API崩溃
- 当检测到目标语音不存在时,调用预下载API发起下载请求,系统会自动弹出下载提示并处理下载流程
- 下载完成后,在回调中继续执行原有的语音识别授权逻辑
修改后的代码示例
private func requestSpeechRecognizerAuthorization(completion: @escaping (SFSpeechRecognizerAuthorizationStatus) -> Void) { let targetVoiceId = "com.apple.voice.enhanced.en-IN.Rishi" let voice = AVSpeechSynthesisVoice(identifier: targetVoiceId) guard voice != nil else { // 检查系统版本是否支持预下载 guard #available(iOS 13.0, *) else { DispatchQueue.main.async { let alert = UIAlertController(title: "语音不可用", message: "当前系统版本不支持应用内下载语音,请前往设置 > 辅助功能 > 朗读内容 > 语音 下载后重试。", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "确定", style: .default)) UIApplication.shared.windows.first?.rootViewController?.present(alert, animated: true) } return } // 发起语音预下载请求 AVSpeechSynthesisVoice.prefetchVoice(withIdentifier: targetVoiceId) { error in DispatchQueue.main.async { if let error = error { // 下载失败,提示用户手动下载 let alert = UIAlertController(title: "下载失败", message: "语音下载失败,请前往设置 > 辅助功能 > 朗读内容 > 语音 手动下载后重试。错误信息:\(error.localizedDescription)", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "确定", style: .default)) UIApplication.shared.windows.first?.rootViewController?.present(alert, animated: true) } else { // 下载成功,重新获取语音并继续授权流程 if AVSpeechSynthesisVoice(identifier: targetVoiceId) != nil { SFSpeechRecognizer.requestAuthorization { authStatus in DispatchQueue.main.async { completion(authStatus) } } } else { let alert = UIAlertController(title: "语音仍不可用", message: "请前往设置 > 辅助功能 > 朗读内容 > 语音 手动下载所需语音后重试。", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "确定", style: .default)) UIApplication.shared.windows.first?.rootViewController?.present(alert, animated: true) } } } } return } // 语音已存在,直接执行授权流程 SFSpeechRecognizer.requestAuthorization { authStatus in DispatchQueue.main.async { completion(authStatus) } } }
注意事项
prefetchVoice方法会触发系统自带的下载弹窗,无需自行实现下载进度提示- 下载过程中用户可以选择取消,此时回调会返回对应的错误信息
- 低版本系统(iOS 12及以下)仍需要引导用户前往设置手动下载
内容的提问来源于stack exchange,提问作者Nat Serrano
相关产品推荐
相关产品推荐

