我在应用程序中实现信标时遇到问题。我正在使用库react-native-beacons-manager
,但我认为这是一个普遍的"问题"。
问题是,当我杀死我的应用程序(这对重现问题很重要),并且我离信标越来越近时,iOS会触发一个事件regionDidEnter
,该事件被用本机代码编写的文件捕获,然后使用RCTEventEmitter
:[self sendEventWithName:@"regionDidEnter" body:event];
的方法发送到javascript
问题是这个事件是在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编写本机信标应用程序时也存在此一般问题。解决方案是,您必须设置"挂钩",以启用信标监控,并在每个平台的适当位置添加事件侦听器(或在本机代码中调用的委托/通知回调):
iOS:AppDelegate.didFinishLanching(options: )
安卓系统:Application.onCreate()
关键是,在这些方法返回之前,必须完成此设置。
同样的规则也适用于ReactNative。ReactNative的诀窍是,默认情况下,JavaScript不会在这些事件上运行——它只在屏幕启动时运行,这会设置挂钩太晚,以至于当你的应用程序被终止时,上述功能无法工作。要实现这一点,你需要弹出你的应用程序,这样你就可以在上面的回调中设置一些自定义的本地代码。
两种选择:
- 本机实现信标检测(最简单,但需要基于每个平台的本机编码)
- 在上面的本机回调中添加本机代码,该回调在iOS上启动
RCTBridge
,并启动一个视图,该视图执行触发我们的JavaScript代码以设置信标检测的代码。在Android上,等效的方法是构建一个新的ReactRootView和ReactNativeInstanceManager,以触发您的JavaScript代码来设置信标检测
我还没有亲自测试选项2,看看它是否能很快设置挂钩。如果它有效,它肯定会比原生解决方案更难,但允许您将信标检测逻辑保留在JavaScript中。
(https://github.com/MacKentoch/react-native-beacons-manager/issues/50)
我已经分叉了@newoceaninfosys的分叉,并添加了"错过信标"方法。查看我最近的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):加载javascript之前的RCTEventEmitter)
希望这能帮助到别人。:)