I’m excited to share a set of mobile apps I’ve recently completed and published on both the Google Play Store and the Apple App Store. These apps are designed with a simple goal in mind: to make meaningful, structured content more accessible, whether you’re studying theology or improving your English vocabulary. 📱 Now Available on Both Platforms All apps are live and available for download: Google Play Developer Page: https://play.google.com/store/apps/dev?id=5835943159853189043 Apple App Store Developer Page: https://apps.apple.com/ca/developer/q-z-l-corp/id1888794100 📖 Theology & Confession Study Apps For those interested in Reformed theology and classical Christian teachings, I’ve developed a series of apps that present foundational texts in a clean, focused reading format: The Belgic Confession Canons of Dort Heidelberg Catechism Westminster Shorter Catechism Each app is designed to provide a distraction-free experience, making it easier to read, reflect, and revisit these im...
React Native TTS iOS 问题全解析:修复 BOOL 错误与事件监听失效(2026 实战指南)
- Get link
- X
- Other Apps
By
Errong Leng
-
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.
- Get link
- X
- Other Apps
Popular Posts
Fix “A problem occurred starting process 'command node'” in Android Studio for React Native
By
Errong Leng
-
Fix “A problem occurred starting process 'command node'” in Android Studio for React Native If you are building a React Native Android project and encounter this error during Gradle sync: A problem occurred evaluating project ':react-native-svg'. > A problem occurred starting process 'command 'node'' —even though node works perfectly in your terminal—this guide will show you how to fix it quickly. Common Misconceptions This error is often mistaken as a Node.js or PATH issue, but that is not always the case. Node.js is installed and working in your terminal. PATH and environment variables appear correct. Still, Android Studio Gradle sync fails with the above error. The Real Cause The issue typically arises because of an incorrect Gradle JDK configuration inside Android Studio . Gradle runs inside a JVM and uses that JVM to spawn external processes (like node ). If the Gradle JDK is incompatible or misconfigured, Gradle will...
Fix up watchman issue with Ghost
By
三好Daddy
-
# Issue >> >> at BunserBuf.<anonymous> (/home/errong_leng/Ghost/core/client/node_modules/fb-watchman/index.js:95:23) >> at emitOne (events.js:116:13) >> at BunserBuf.emit (events.js:211:7) >> at BunserBuf.process (/home/errong_leng/Ghost/core/client/node_modules/bser/index.js:292:10) >> at /home/errong_leng/Ghost/core/client/node_modules/bser/index.js:247:12 >> at _combinedTickCallback (internal/process/next_tick.js:131:7) >> at process._tickCallback (internal/process/next_tick.js:180:9) >> A non-recoverable condition has triggered. Watchman needs your help! >> The triggering condition was at timestamp=1509698956: inotify-add-watch(/home/errong_leng/Ghost/core/client/node_modules/ember-cli-node-assets/node_modules/broccoli-funn...
Using Mutual TLS (mTLS) in Next.js (Server-Side Only)
By
三好Daddy
-
Using Mutual TLS (mTLS) in Next.js (Server-Side Only) In the previous posts, we covered: Part 1: Making mTLS API requests from Node.js clients Part 2: Enabling mTLS in Node.js servers Now we focus on Next.js applications and how mTLS works depending on deployment. Next.js Cannot Access TLS Handshake Directly Next.js middleware and API routes run after the TLS handshake They cannot see client certificates or verify them Next.js built-in server does not expose Node's HTTPS options like requestCert In short: Next.js middleware cannot enforce mTLS or access TLS handshake details . Any enforcement must happen before the request reaches Next.js. Next.js as an mTLS Client (Server-Side API Calls) Next.js can securely call mTLS-protected APIs from server-side code, such as: API routes Server actions import fs from 'fs'; import https from 'https'; import axios from 'axios'; export async function GET(req) { const...
Comments
Post a Comment