React Native (iOS):加载 javascript 之前的 RCTEventEmitter

React Native (iOS): RCTEventEmitter before javascript is loaded

我在我的应用程序中实施信标时遇到问题。我正在使用库react-native-beacons-manager,但我认为是一般的"problem"。

问题是,当我终止我的应用程序(这对于重现问题很重要)并且靠近我的信标时,iOS 触发一个事件 regionDidEnter用本机代码编写的文件,然后使用 RCTEventEmitter 的方法发送到 javascript:[self sendEventWithName:@"regionDidEnter" body:event];

问题是这个事件在 javascript 完全加载之前触发,所以我的听众:

// component.js
Beacons.BeaconsEventEmitter.addListener('regionDidEnter', b => {
        //code
      });

没有接到电话。

事件顺序:

[BeaconsDemo] Did finish launching enter
[BeaconsDemo] Did finish launching After jsBundleURLForBundleRoot
[BeaconsDemo] Did finish launching After RCTRootView alloc
[BeaconsDemo] Did finish launching After UIWindow alloc
[BeaconsDemo] Did finish launching After makeKeyAndVisible
[BeaconsDemo] Did finish launching end
--iOS send the event and it is caught by RNiBeacon but it has no listeners yet--
[BeaconsDemo] no listeners in RnIBeacon.m
--Register
[BeaconsDemo] regionDidExit
-- First line of javascript --
[BeaconsDemo] start observing
[BeaconsDemo] requestAlwaysAuth

有处理这种情况的想法吗?有什么方法可以通过 RCTEventEmitter 发送事件以等待 javascript 加载?

谢谢

为 iOS 或 Android 编写本机信标应用程序时也存在此普遍问题。解决方案是您必须设置 "hook" 以启用信标监视并在每个平台的适当位置添加事件侦听器(或在本机代码中调用的委托/通知回调):

iOS: AppDelegate.didFinishLanching(options: )

Android: Application.onCreate()

关键是这个设置必须在那些方法之前完成return。

同样的规则适用于 ReactNative。 ReactNative 的诀窍是,默认情况下 JavaScript 不会 运行 处理这些事件——它仅在屏幕启动时才 运行s,这为上面的事件设置挂钩太晚了在您的应用程序被杀死时工作。要让它工作,您需要弹出您的应用程序,以便您可以在上述回调中设置一些自定义本机代码。

两个选项:

  1. 本机实现信标检测(最简单,但需要在每个平台基础上进行本机编码)
  2. 在上面的本机回调中添加本机代码,在 iOS 上启动 RCTBridge,并启动一个视图来执行触发我们的 JavaScript 代码以设置信标检测的代码。在 Android 上,等效的方法是构建一个新的 ReactRootView 和 ReactNativeInstanceManager,它会触发您的 JavaScript 代码以设置信标检测。

我还没有亲自测试选项 2,看它是否可以足够快地设置挂钩。如果可行,它肯定会比本机解决方案更难,但允许您将信标检测逻辑保留在 JavaScript.

(https://github.com/MacKentoch/react-native-beacons-manager/issues/50)

我分叉了@newoceaninfosys 的分叉并添加了 'missed beacon' 方法。检查我最近的 3 次提交,了解如何复制它。 (https://github.com/iamandiradu/react-native-beacons-manager) 通过在 didMount 函数中添加它来使用它:

if (Platform.OS === 'ios') { // iOS cold start listener this.beaconMissedListener = Beacons.BeaconsEventEmitter.addListener( 'onMissedBeacon', data => { if (data) { this._beaconListener(data); } }, ); Beacons.getMissedBeacon(); }

这将检索获得 'lost' 的数据,因为事件触发速度比侦听器快。

()

希望这对某人有所帮助。 :)