新手入门 React-Native 开发iOS原生和React-Native三种通信方式和一些遇到的小坑

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容