React Native TTS iOS 问题全解析:修复 BOOL 错误与事件监听失效(2026 实战指南)

React Native TTS iOS 问题全解析:修复 BOOL 错误与事件监听失效(2026 实战指南)



在 React Native 中使用文本转语音(TTS)本来很简单,但在 iOS 上却可能踩坑。

本文总结了两个非常常见但又很隐蔽的问题,并提供经过验证的解决方案。


🧨 问题一:Objective-C type BOOL is unsupported

错误信息

TextToSpeech.setDefaultRate(): 
Error while converting JavaScript argument to Objective C type BOOL
convert javascript argument to object C type Bool
object C type bool is unsupported

🔍 根本原因

不是你的代码问题

这是由于 iOS 原生桥接层(Objective-C)类型定义错误导致的,尤其在 React Native 新架构(Fabric / TurboModules)下更容易触发。

部分版本的 react-native-tts 错误地使用了:

(BOOL *)onWordBoundary   ❌ 错误

而 React Native bridge 不支持 BOOL 指针类型,只支持:

  • BOOL
  • NSNumber *

✅ 解决方案

使用已修复的 fork 版本:

@iternio/react-native-tts

npm install @iternio/react-native-tts

该版本已修复 iOS 类型问题,可以正常运行。


⚠️ 问题二:事件监听器未注册

警告信息

Sending `tts-start` with no listeners registered.

即使你已经写了监听:

Tts.addEventListener('tts-start', () => {
  setIsSpeaking(true);
});

🔍 根本原因

问题在于:TTS 模块尚未初始化完成,你就注册了监听器。

  • Native 层事件已触发 ✅
  • JS 监听器尚未就绪 ❌

✅ 关键修复(必须做)

在使用 TTS 前,必须等待初始化:

useEffect(() => {
  const init = async () => {
    await Tts.getInitStatus(); // 👈 非常关键

    Tts.setDefaultRate(0.5);
    Tts.setDefaultPitch(1.0);

    const sub = Tts.addEventListener('tts-start', () => {
      setIsSpeaking(true);
    });

    return () => sub.remove();
  };

  init();
}, []);

💡 总结

  • react-native-tts 在 iOS 上存在已知问题
  • BOOL 错误属于 Native 层 bug,不是 JS 写法问题
  • 必须调用 Tts.getInitStatus() 再使用

🚀 推荐实践

  • ✅ 使用 @iternio/react-native-tts
  • ✅ 所有调用前等待初始化
  • ⚠️ 新架构(Fabric)下需特别注意兼容性

🧩 进阶建议

如果你在开发生产级应用,建议直接封装 iOS 原生 TTS:

  • 使用 AVSpeechSynthesizer
  • 自定义 React Native bridge

这样可以彻底避免第三方库带来的不稳定问题。


✍️ 结语

这些问题非常隐蔽,但其实很常见。如果你也遇到类似问题,希望这篇文章能帮你节省大量排查时间。

Happy coding 🚀

❤️ Support This Blog


If this post helped you, you can support my writing with a small donation. Thank you for reading.


Comments

Popular posts from this blog

fixed: embedded-redis: Unable to run on macOS Sonoma

Copying MDC Context Map in Web Clients: A Comprehensive Guide

Reset user password for your own Ghost blog