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

时间:2019-01-15 14:04:01

标签: javascript react-native ibeacon

我在应用程序中实施信标时遇到问题。我正在使用库react-native-beacons-manager,但我认为这是一个普遍的“问题”。

问题是,当我杀死我的应用程序(这对于重现该问题很重要)并且离我的信标越来越近时,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加载完毕?

谢谢

2 个答案:

答案 0 :(得分:0)

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

iOS: AppDelegate.didFinishLanching(options: )

Android: Application.onCreate()

关键是必须在这些方法返回之前完成此设置。

此规则也适用于ReactNative。 ReactNative的诀窍在于,默认情况下,JavaScript不会在这些事件上运行-它仅在启动屏幕时运行,这将使钩子设置得太迟,以至于您的应用被杀死时,上述方法无法正常工作。要使其正常工作,您需要退出您的应用程序,以便可以在上述回调中设置一些自定义本机代码。

两个选项:

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

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

答案 1 :(得分:0)

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(); }

这将检索丢失的数据,因为事件的触发速度比侦听器快。

React Native (iOS): RCTEventEmitter before javascript is loaded

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