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;

     onPress={()=>this.callBackEvent()}>

       {/callback-方式点击调原生+回调/}

实现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引用代码实现

onPress={()=>this.promisesEvent()}>

 Promise回调-方式

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 { ZeroBridgeWebViewview = [[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(

this.onMessage()}>

        );

    }

}

//这个坑害了我好久的。。

onMessage(){

}

5.一些遇到的其他的坑。。也是网上找了半天才解决的。。。

1.Duplicate interface definition for class ‘RCTView’ 或者类似的错误都这样解决

这个错误解决办法:#import “RCTView.h” 替换成 #import

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.还有一些其他的混合问题。。各种引用的问题。。私信我有时间给你下回答。。

文章来源于互联网:新手入门 React-Native 开发iOS原生和React-Native三种通信方式和一些遇到的小坑

发表评论