美文网首页
RN和原生互调

RN和原生互调

作者: Mr_Legend | 来源:发表于2016-11-21 13:12 被阅读1844次

    本来当天就应该把这部分写完,现在隔了一天 ,决定停止RN学习。
    原因有几点吧:
    1、对于iOS(原生)移动开发者来说,学习RN,相较于 前端开发学习RN并使用Xcode添加基本配置来说,所需要的时间和精力是不对称的。
    2、对于初创公司,使用RN技术远比原生开发节约大量成本。
    对于上市公司(我现在的公司),逐渐节约成本,逐渐精简人员(移动开发人员地位与日俱降),也是产品快速发展的需求,举个🌰:微软全线产品都支持RN。
    3、个人原因


    这里总结下RN<->iOS 互调的使用

    第一步:原生 传参 给RN:

    oc代码:
    穿参数有两种方式

    • 通过initialProperties属性来传递。
    NSURL *jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"];
        NSDictionary *props = @{
                                @"scores" : @[
                                        @{
                                            @"name" : @"Alex",
                                            @"value": @"42"
                                            },
                                        @{
                                            @"name" : @"Joel",
                                            @"value": @"10"
                                            }
                                        ]
                                };
        RCTRootView *rootView =
        [[RCTRootView alloc] initWithBundleURL : jsCodeLocation
                                   moduleName  : @"rn_testAddRNIntoProject"
                             initialProperties :props
                              launchOptions    : nil];
    
    • 通过RCTRootView的appProperties属性
      Paste_Image.png

    js代码:

    //创建原生模块实例
    class myRNClass extends React.Component {
      render() {
        var contents = this.props["scores"].map(
          score => <Text key={score.name}>{score.name}:{score.value}{"\n"}</Text>
        );
        return (
          <View style={styles.container}>
            <Text style={styles.highScoresTitle}>
              2048 High Scores!
            </Text>
            <Text style={styles.scores}>
              {contents}
            </Text>
          </View>
        );
      }
    }
    

    第二步:RN 调用 原生iOS方法

    oc代码:
    在React Native中,一个“原生模块”就是一个实现了“RCTBridgeModule”协议的Objective-C类

    #import <Foundation/Foundation.h>
    #import <RCTBridgeModule.h>
    @interface NativeTest : NSObject<RCTBridgeModule>
    
    @end
    
    #import "NativeTest.h"
    
    @implementation NativeTest
    
    //注意:为了实现RCTBridgeModule协议,你的类需要包含RCT_EXPORT_MODULE()宏
    
    RCT_EXPORT_MODULE();    //此处不添加参数即默认为这个OC类的名字
    
    //导出方法,桥接到js的方法返回值类型必须是void
    RCT_EXPORT_METHOD(doSomething:(NSString *)name)
    {
        NSLog(@"doSomething:%@",name);
    }
    @end
    

    js代码:

    import {
      NativeModules,
      NativeAppEventEmitter
    } from 'react-native';
    
    /**
     * [RN调用原生]
     */
    var myNativeTest = NativeModules.NativeTest;
    class myRNClass extends React.Component {
      render() {
        return (
              <TouchableHighlight onPress={ ()=>myNativeTest.doSomething('test')}>
                <Text style={styles.text}>
                点击
                </Text>
              </TouchableHighlight>
        );
      }
    }
    

    桥接到Javascript的方法返回值类型必须是void。React Native的桥接操作是异步的,所以要返回结果给Javascript,你必须通过回调或者触发事件来进行

    oc代码:

    RCT_EXPORT_METHOD(doOther:(NSString *)name callback:(RCTResponseSenderBlock)callback)
    {
        NSLog(@"doOther:");
        NSArray *array = @[@"abc",@"acb"];
        callback(@[[NSNull null],array]);
    }
    

    js代码:

    /**
     * 传参数并带有回调
     */
    class myRNTest extends React.Component {
      render() {
        return (
              <TouchableHighlight onPress={ ()=>{myNativeTest.doOther(
                'test',(error,events)=>{
                  if (error) {
                    console.error(error);
                  }else {
                    console.log('传值成功');
                    this.setState({events:events});
                  }
                }
                )}}>
                <Text style={styles.text}>
                点击
                </Text>
              </TouchableHighlight>
        );
      }
    }
    

    任何RCTConvert类支持的的类型也都可以使用
    RCTConvert还提供了一系列辅助函数,用来接收一个JSON值并转换到原生Objective-C类型或类.

    #import "RCTConvert.h"
    #import "RCTBridge.h"
    #import "RCTEventDispatcher.h"
    //  对外提供调用方法,为了演示事件传入属性字段
    RCT_EXPORT_METHOD(testDictionaryEvent:(NSString *)name details:(NSDictionary *) dictionary)
    {
        NSString *location = [RCTConvert NSString:dictionary[@"thing"]];
        NSDate *time = [RCTConvert NSDate:dictionary[@"time"]];
        
        NSString *info = [NSString stringWithFormat:@"Test: %@\nFor: %@\nTestTime: %@",name,location,time];
        NSLog(@"%@", info);
    }
    

    第三步:OC原生 调用 RN


    相关文章

      网友评论

          本文标题:RN和原生互调

          本文链接:https://www.haomeiwen.com/subject/wkqupttx.html