React Native iOS中sendEventWithName触发‘RCTCallableJSModules未设置’崩溃
我有两个React Native应用,仅Bundle ID和应用图标不同,代码结构完全一致。需求是当应用处于前台且启动完成时,用户接收或点击推送通知后,通过原生桥接向JS层发送事件。其中A应用使用命令xcrun simctl push <device-id> <bundleId> <filename>.apns触发通知时正常工作,但B应用会立即崩溃,报错信息如下:
Thread 1: "Error when sending event: pushDelivered with body: <传入的字符串>. RCTCallableJSModules is not set. This is probably because you've explicitly synthesized the RCTCallableJSModules in CustomEventsEmitter, even though it's inherited from RCTEventEmitter."
我已经尝试过重新安装Pod、清理项目并重建,但问题依旧。请求帮忙排查问题原因,是否与桥接有关?
核心原因分析
报错信息已经明确指向问题:你的CustomEventsEmitter类中显式合成了RCTCallableJSModules属性,但该属性是从RCTEventEmitter父类继承而来的,完全不需要手动合成。手动合成会覆盖父类的内部实现逻辑,导致RN框架无法正确初始化这个关键属性,最终触发发送事件时的崩溃。
尽管两个应用结构一致,但可能B应用的CustomEventsEmitter代码中存在这行冗余的合成代码,或是Xcode编译过程中,B应用的类扩展/分类意外引入了该逻辑。
具体修复步骤
检查
CustomEventsEmitter实现文件- 打开
CustomEventsEmitter.m(或.mm)文件,查找是否存在如下代码:@synthesize RCTCallableJSModules; - 如果存在,直接删除这行代码并保存。
- 打开
排查分类/扩展文件
- 检查是否有针对
CustomEventsEmitter的分类(Category)或扩展(Extension)文件,若其中同样包含@synthesize RCTCallableJSModules;,一并删除。
- 检查是否有针对
彻底清理并重新编译
- 执行以下命令完成全量清理:
# 清理React Native缓存 npx react-native clean # 清理Xcode编译缓存 xcodebuild clean -workspace YourApp.xcworkspace -scheme YourApp -configuration Debug # 重新安装Pod依赖 cd ios && pod install && cd .. - 重新启动B应用,再次用
xcrun simctl push命令测试推送通知。
- 执行以下命令完成全量清理:
验证桥接初始化逻辑
- 对比A应用的AppDelegate代码,确保B应用中
CustomEventsEmitter的初始化和注册流程完全一致,示例正确逻辑如下:// AppDelegate.m #import "CustomEventsEmitter.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 其他初始化代码... RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; CustomEventsEmitter *eventsEmitter = [[CustomEventsEmitter alloc] initWithBridge:bridge]; [bridge.moduleClasses addObject:[CustomEventsEmitter class]]; // 后续代码... } - 确认B应用没有遗漏
initWithBridge:初始化方法,也没有手动给RCTCallableJSModules赋值的操作。
- 对比A应用的AppDelegate代码,确保B应用中
额外排查点
- 核对两个应用的React Native版本是否完全一致(部分旧版本RN的
RCTEventEmitter可能不包含该属性,若B应用单独升级过RN版本,可能引发冲突) - 检查Xcode中B应用的编译选项,是否存在特殊预编译宏或编译参数导致代码行为异常
内容的提问来源于stack exchange,提问作者se09deluca

