You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否通过编程方式下载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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 16:27:08