1.callback回调方式,RN触发事件回调iOS原生的数据
例如代码:
io部分代码
//定义导出的模块名
RCT_EXPORT_MODULE()
//定义导出的方法名
RCT_EXPORT_METHOD(pushEvent:(NSString *)event callback:(RCTResponseSenderBlock)callback){
NSLog(@"----对React Native提供调用方法,Callback---%@",event);
NSString *callbackData = @"原生数据被RN调用"; //准备回调回去的数据
callback(@[[NSNull null],callbackData]);
}
React-Native引用
var ZeroCallbackModule = NativeModules.ZeroCallbackModule;
<Txet 自己设置大小样式>
onPress={()=>this.callBackEvent()}>
{/*callback-方式点击调原生+回调*/}
</Text>
实现rn和iOS通信回调
callBackEvent (){
ZeroCallbackModule.pushEvent(('RN->原生的数据'),(error, events) => {
if (error) {
console.log(error);
}else {
alert(events)//返回的数据
}
})
}
2.promise实现的回调函数我自己的理解类似于iOS的block回调方式。。。新手理解!!
iOS部分代码
static RCTPromiseResolveBlock _resolve;
static RCTPromiseRejectBlock _reject;
RCT_REMAP_METHOD(pushPromisesEvent,
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject){
_resolve = resolve;
_reject = reject;
[[ZeroHttpRquestManager sharedManager]requestPostWithPath:@"http" completed:^(BOOL ret, id obj) {
[ZeroCallbackModule handleResult:obj];
}];
}
+(void) handleResult:(id)result{
//原生Promises数据被RN调用
if ([result isEqualToString:@"获取数据成功"]) {
_resolve(@[result]);
}else{
//返回错误信息
NSError *error=[NSError errorWithDomain:result code:101 userInfo:nil];
_reject(@"no_events", @"There were no events", error);
}
}
RCT_REMAP_METHOD(promisesEvent,
presolver:(RCTPromiseResolveBlock)resolve
prejecter:(RCTPromiseRejectBlock)reject){
NSString *PromisesData = @"原生Promises数据被RN调用";
if (PromisesData) {
resolve(PromisesData);
} else {
NSError *error=[NSError errorWithDomain:@"我是Promise回调错误信息..." code:101 userInfo:nil];
reject(@"no_events", @"There were no events", error);
}
}
rn引用代码实现
<Text 自己设置大小样式
onPress={()=>this.promisesEvent()}>
Promise回调-方式
</Text>
async promisesEvent(){
ZeroCallbackModule.pushPromisesEvent().then((events)=>{
alert(events+1111)
}).catch((e)=>{
// alert(e)
console.log("错误信息------"+e);
})
}
3.类似iOS的通知模式 RCTEventEmitter
1.继承这个类
@interface ZeroBridgeEventEmitter : RCTEventEmitter
@end
2.iOS代码实现
- (NSArray *)supportedEvents{
return@[@"data ",@"callback ",@"event"];
}
//发送消息代码。。在iOS端自己做一个触发事件处理
-(void)message:(NSString*)callback event:(NSString*)event target:(id)target{
[self sendEventWithName:@"onChange"
body:@{
@"callback": callback,
@"event": event,
@"target":target,
}];
}
3.RN引用代码(如果引用有坑。。就是iOS端做一个触发事件去触发)
componentDidMount(){
NativeModule.addListener('onChange',(data)=>this.message(data));
}
message (data) {//body 看你传什么
console.log('————————————————————'+data);
alert('hahhaahah');
}
componentWillUnmount() {
//删除监听
this.NativeModule.remove()
}
4.关键是在于RN引用的问题。。。网上例子很多的。。但是真正自己去使用的时候发现存在有问题。。我说下我们公司的项目。。是H5写的项目嵌入到RN中使用。。但是还必须自己在iOS端自定义一个UIWebView来加载H5的页面运行。。。所以我自己还是遇到了很多的坑的。。。发现这个方法使用的话。。不适合自己项目的场景。。而且之前android端定义好了很多方法和实现方式。。导致我很被动的只能按照那种方式实现。。。
iOS端自定义的UIWebView通过继承于RCTViewManager的类给RN使用
倒入头文件类
@interface ZeroBridgeWebViewManager ()
@property (nonatomic, strong) RCTBridge *bridge;
@end
@implementation ZeroBridgeWebViewManager
RCT_EXPORT_MODULE(ZeroBridgeWebViewManager)
这里是原生的属性给rn使用
RCT_EXPORT_VIEW_PROPERTY(statusBarHeight, NSInteger)RCT_EXPORT_VIEW_PROPERTY(messagingEnabled, BOOL)RCT_EXPORT_VIEW_PROPERTY(isNotice, BOOL)RCT_EXPORT_VIEW_PROPERTY(bottomNavHeight, NSInteger)RCT_EXPORT_VIEW_PROPERTY(currentPage, NSDictionary)RCT_EXPORT_VIEW_PROPERTY(url, NSString)
/**重写这个方法,返回将要提供给RN使用的视图*/
- (UIView *)view { ZeroBridgeWebView*view = [[ZeroBridgeWebView alloc]initWithFrame:[UIScreen mainScreen].bounds];
view.delegate = self;
return view;
}
/**获取当前试图View*/
- (ZeroBridgeWebView*) getViewWithTag:(NSNumber *)tag {
NSLog(@"%@", [NSThread currentThread]);
UIView *view = [self.bridge.uiManager viewForReactTag:tag];
return [view isKindOfClass:[ZeroBridgeWebView class]] ? (ZeroBridgeWebView *)view : nil;
}
/**当前显示线程队列*/
- (dispatch_queue_t)methodQueue
{ return dispatch_get_main_queue();
}
- (NSArray *)supportedEvents
{
/**注意最坑的就是这了。。。在RN中引用UIWebView的方法是onMessage他在这里要写成topMessage*/
return @[@"topMessage"];
}
#pragma mark-这里是点击webView代理回调事件
- (void)webView:(UIWebView *)webView didFinishLoad:(NSURL *)load{
/**很坑的这个topMessage*/
[self.bridge.eventDispatcher sendAppEventWithName:@"topMessage"
body:@{
@"code": @"发送的参数",
@"result": @"发送的参数",
@"body": @"发送的参数",
}];
}
var RCBridgeWebView = requireNativeComponent('ZeroBridgeWebView', BridgeWebView);
export default class BridgeWebView extends Component {
// 与OC中 RCTViewManager子类中导出的属性对应
static propTypes = {
value: React.PropTypes.number,
isTest1: React.PropTypes.bool,
num: React.PropTypes.number,
infoDict: React.PropTypes.object,
url: React.PropTypes.string,
};
componentDidMount() {
console.log("MyView被加载了");
}
render() {
return(
<RCBridgeWebView onMessage={()=>this.onMessage()}>
</RCBridgeWebView>
);
}
}
//这个坑害了我好久的。。
onMessage(){
}
5.一些遇到的其他的坑。。也是网上找了半天才解决的。。。
1.Duplicate interface definition for class 'RCTView' 或者类似的错误都这样解决
这个错误解决办法:#import "RCTView.h" 替换成 #import<React/RCTView.h>
2.出现错误 ld: library not found for -lRNDeviceInfo-tvOS或者类似的错误。。
clang: error: linker command failed with exit code 1 (use -v to see invocation) 这个错误
解决办法: 删掉这个库文件在
3.出现问题解决Xcode中 RSKImageCropper.framework和QBImagePicker.framework报错问题
http://blog.csdn.net/u013718120/article/details/72781285
4.还有一些其他的混合问题。。各种引用的问题。。私信我有时间给你下回答。。