【发布时间】:2017-04-06 04:59:56
【问题描述】:
我已经创建了以下类(精简版),这里是对完整文件的引用 https://github.com/cotyembry/CastRemoteNative/blob/7e74dbc56f037cc61241f6ece24a94d8c52abb32/root/ios/CastRemoteNative/NativeMethods.swift
@objc(NativeMethods)
class NativeMethods: RCTEventEmitter {
@objc(sendEventToJSFromJS)
func sendEventToJSFromJS {
self.emitEvent(eventName: "test", body: "bodyTestString")
}
func emitEvent(eventName: String: body: Any) {
self.sendEvent(withName: eventName, body: body)
}
}
当我像下面这样调用emitEvent 方法时,它完美地工作并触发我的javascript代码中的回调侦听器,它是一个改变的sn-p
https://github.com/cotyembry/CastRemoteNative/blob/7e74dbc56f037cc61241f6ece24a94d8c52abb32/root/js/Components/ChromecastDevicesModal.js
从 javascript 方面
import {
NativeModules,
NativeEventEmitter
} from 'react-native'
//here I bring in the swift class to use inside javascript
var NativeMethods = NativeModules.NativeMethods;
//create an event emitter to use to listen for the native events when they occur
this.eventEmitter = new NativeEventEmitter(NativeMethods);
//listen for the event once it sends
this.subscription = this.eventEmitter.addListener('test', (body) => { console.log('in test event listener callback', body)});
NativeMethods.sendEventToJSFromJS() //call the native method written in swift
我只是在 javascript 中按下按钮时调用 sendEventToJSFromJS 方法
同样,这有效,console.log('in test event listener callback', body) 代码在 javascript 端有效并运行
这不起作用的我的问题:
如果我在定义类后在 swift 文件中执行以下操作,这将不起作用:
var nativeMethodsInstance = nativeMethods()
nativeMethodsInstance.sendEventToJSFromSwift()
为什么?因为抛出如下错误:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'bridge is not set. This is probably because you've explicitly synthesized the bridge in NativeMethods, even though it's inherited from RCTEventEmitter.'
那么,在创建NativeMethods 的instance 时,与不...有什么区别?
更多信息:
当我在 .h 和 .m 文件而不是 .swift 文件中编写这些相同的 sn-ps 代码时,Objective-C 会遇到相同的桥未设置问题
我发现错误消息在本机代码中打印的位置,但它只有变量
_bridge
并且正在检查它是否是nil
此错误来自的文件是:
RCTEventEmitter.h
RCTEventEmitter.c
这是RCTEventEmitter.c的完整sn-p
- (void)sendEventWithName:(NSString *)eventName body:(id)body
{
RCTAssert(_bridge != nil, @"bridge is not set. This is probably because you've "
"explicitly synthesized the bridge in %@, even though it's inherited "
"from RCTEventEmitter.", [self class]);
if (RCT_DEBUG && ![[self supportedEvents] containsObject:eventName]) {
RCTLogError(@"`%@` is not a supported event type for %@. Supported events are: `%@`",
eventName, [self class], [[self supportedEvents] componentsJoinedByString:@"`, `"]);
}
if (_listenerCount > 0) {
[_bridge enqueueJSCall:@"RCTDeviceEventEmitter"
method:@"emit"
args:body ? @[eventName, body] : @[eventName]
completion:NULL];
} else {
RCTLogWarn(@"Sending `%@` with no listeners registered.", eventName);
}
}
这个 _bridge 值在哪里设置以及它是如何设置的,所以我可以知道,在它失败的情况下如何设置它
我还在 RCTEventEmitter.h 中找到了以下内容
@property (nonatomic, weak) RCTBridge *bridge;
在给出的错误中提到桥是在 RCTEventEmitter 中继承的,那么这可能是 bridge 属性的 weak 部分的问题吗?
或者我是否需要改变我如何一起做这一切的策略?
我知道这可能与我没有完全理解有关
@synthesize bridge = _bridge;
部分代码和混入的所有语言都没有多大帮助,哈哈……
这真的很难,所以任何帮助将不胜感激! 非常感谢您的宝贵时间
当项目历史代码代表我上面问题中的代码时,这里是一个完整项目的链接(因为我已经对项目进行了更改):
https://github.com/cotyembry/CastRemoteNative/tree/7e74dbc56f037cc61241f6ece24a94d8c52abb32
【问题讨论】:
标签: javascript ios swift react-native event-handling