一开始以为是移动端中注入的方法 和 js方法名不对。经排查,是一致的。
然后排查 注入方法(通过 - (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler注入)也没有任何问题。
后来发现前端是使用的vue框架,而直接将js方法写在 methods 中,这样造成这个交互js方法是局部的,无法被ios端找到。
解决办法:将iOS需要调用的js方法在 created 和 mounted 方法中暴露在window下,变成全局方法。
window.printText = this.printText()
如果到这里还不行或者有崩溃,请在 window.onload 方法下进行声明
ReactEventEmit.h
#import <React/RCTEventEmitter.h>
#import <React/RCTBridgeModule.h>
@interface ReactEventEmit : RCTEventEmitter<RCTBridgeModule>
-(void)goToCashier:(NSString*) result
@end
ReactEventEmit.m
#import "ReactEventEmit.h"
@implementation ReactEventEmit
@synthesize bridge = _bridge
RCT_EXPORT_MODULE(ReactEventEmit)
+ (id)allocWithZone:(NSZone*)zone {
staticReactEventEmit*sharedInstance =nil
staticdispatch_once_tonceToken
dispatch_once(&onceToken, ^{
sharedInstance = [superallocWithZone:zone]
})
returnsharedInstance
}
-(NSArray *)supportedEvents{
return @[@"goToCashier"]
}
-(void)goToCashier:(NSString*) result
{
NSLog(@"======== cashierSuccess ========== %@",result)
[self sendEventWithName:@"goToCashier" body:@{@"result": result}]
}
@end
RN的module初始化是由RN内部实现的,所以我们调用这个实例的时候,必须是这样子:
ReactEventEmit *emit = [ReactEventEmit allocWithZone:nil]
[emit goToCashier:@"fail"]
JS端调用:
const ReactEventEmit = NativeModules.ReactEventEmit
const myReactEventEmit = new NativeEventEmitter(ReactEventEmit)
this.listener = myReactEventEmit.addListener('goToCashier', (data: { result: string }) =>{
console.warn('====== cashierSuccess ======= ' + JSON.stringify(data))
this.process(data.result)
})
使用示例: 下面的示例代码将调用上面NativeOcClass的方法,在js层只需要这样调用: var ret = jsb.reflection.callStaticMethod("NativeOcClass", "callNativeUIWithTitle:andContent:", "cocos2d-js", "Yes! you call a Native UI from Reflect.