React-Native 学习RN和iOS交互

一:iOS传递数据到RN
1:iOS可以在初始化RCTRootView的时候传递props值;

NSURL *jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"RNInteractive" fallbackResource:nil];

NSArray *imageList = @[@{@"name" : @"jj"},
                         @{@"name" : @"dd"}];
 NSDictionary *props = @{@"soure" : imageList};
 _rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"Rninteractive"
                                               initialProperties:props
                                                   launchOptions:nil];

2:可以通过appProperties的属性重新设置props值;

NSArray *imageList = @[@{@"name" : @"dsssss"},
                         @{@"name" : @"dfffff"}];
  NSDictionary *props = @{@"soure" : imageList};
  _rootView.appProperties = props;

3:使用通知方式传递数据到RN

iOS代码发送通知:
//需要包含的头文件
#import <React/RCTEventDispatcher.h>
#import <React/RCTBridge.h>
[self.bridge.eventDispatcher sendAppEventWithName:@"EventNotification"
                                               body:@{@"name": @"nnnnnnn"}];
RN代码接收通知:
//创建一个监听收到的通知,需要组件NativeAppEventEmitter
var listener = NativeAppEventEmitter.addListener(
    'EventNotification', //监听的通知名称
    (reminder) => console.log(reminder.name, '收到的通知')
);

二:RN传递数据到iOS
iOS提供外调的接口,需要实现RCTBridgeModule协议

//  必须实现
RCT_EXPORT_MODULE();

//对外提供方法,传递字符串
RCT_EXPORT_METHOD(testNormalEvent:(NSString *)name forSomething:(NSString *)thing) {
  NSString *info = [NSString stringWithFormat:@"%s: %@\nFor: %@",__FUNCTION__, name, thing];
  NSLog(@"%@", info);
}

//对外提供方法,传递字典
RCT_EXPORT_METHOD(testDictEvent:(NSString *)name details:(NSDictionary *) dictionary) {
  NSString *info = [NSString stringWithFormat:@"%s: %@\nFor: %@",__FUNCTION__, name, dictionary];
  NSLog(@"%@", info);
}

//对外提供方法,传递回调
RCT_EXPORT_METHOD(testCallbackEvent:(NSString *)name cb:(RCTResponseSenderBlock)callback) {
  NSLog(@"--%s,----%@",__FUNCTION__, name);
  NSArray *events=@[@"你打我看看啊 ", @"test ", @" array"];
  callback(@[[NSNull null], events]);
}

//设置常量给RN进行调用
- (NSDictionary *)constantsToExport {
  //此处定义的常量为RN通知的通知名
  return @{@"receiveNotificationName": @"receive_notification_test"};
}
//对外提供通知方法,接收js的通知
RCT_EXPORT_METHOD(startReceiveNotification:(NSString *)name) {
  NSLog(@"--%s--, ----%@", __FUNCTION__, name);
  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(calendarEventReminderReceived:)
                                               name:name
                                             object:nil];
}

RN调用iOS提供的方法传递数据

//普通传递数据
    touchtestNormalEvent = () => {
        console.log('touchtestNormalEvent');
        caManager.testNormalEvent('超级无敌帅', '老子是逗比');
    };

    //字典传递
    touchtestDictEvent = () => {
        console.log('touchtestDictEvent');
        caManager.testDictEvent('超级无敌帅2号', {'name': 'wwww', 'age': 18, 'date': date})
    };

    //闭包回调
    touchtestCallbackEvent = () => {
        console.log('touchtestCallbackEvent');
        caManager.testCallbackEvent('超级无敌帅3号', (error, events) => {
            if (error) {
                console.log('error =', error)
            }else {
                console.log('events =', events)
            }
        })
    };

    //通知传递
    touchreceiveNotification = () => {
        //receiveNotificationName通知名由iOS原生提供
        caManager.startReceiveNotification(caManager.receiveNotificationName);
    }

iOS完整代码:

#import "Test1ViewController.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTBridgeModule.h>
//#import <React/RCTConvert.h>
#import <React/RCTEventDispatcher.h>
#import <React/RCTBridge.h>


@interface Test1ViewController ()<RCTBridgeModule>

@property (nonatomic, strong) RCTRootView *rootView;

@end

@implementation Test1ViewController
@synthesize bridge = _bridge;

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
  
  NSURL *jsCodeLocation;

  jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"RNInteractive" fallbackResource:nil];

  NSArray *imageList = @[@{@"name" : @"jj"},
                         @{@"name" : @"dd"}];
  
  NSDictionary *props = @{@"soure" : imageList};
  _rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                      moduleName:@"Rninteractive"
                                               initialProperties:props
                                                   launchOptions:nil];
  self.view = _rootView;
  
  UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
  button.frame = CGRectMake(100, 100, 100, 100);
  button.backgroundColor = [UIColor redColor];
  [button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
  [self.view addSubview:button];
}

- (void)buttonAction:(id)sender {
  NSArray *imageList = @[@{@"name" : @"dsssss"},
                         @{@"name" : @"dfffff"}];
  NSDictionary *props = @{@"soure" : imageList};
  _rootView.appProperties = props;
}

//  必须实现
RCT_EXPORT_MODULE();

//对外提供方法,传递字符串
RCT_EXPORT_METHOD(testNormalEvent:(NSString *)name forSomething:(NSString *)thing) {
  NSString *info = [NSString stringWithFormat:@"%s: %@\nFor: %@",__FUNCTION__, name, thing];
  NSLog(@"%@", info);
}

//对外提供方法,传递字典
RCT_EXPORT_METHOD(testDictEvent:(NSString *)name details:(NSDictionary *) dictionary) {
  NSString *info = [NSString stringWithFormat:@"%s: %@\nFor: %@",__FUNCTION__, name, dictionary];
  NSLog(@"%@", info);
}

//对外提供方法,传递回调
RCT_EXPORT_METHOD(testCallbackEvent:(NSString *)name cb:(RCTResponseSenderBlock)callback) {
  NSLog(@"--%s,----%@",__FUNCTION__, name);
  NSArray *events=@[@"你打我看看啊 ", @"test ", @" array"];
  callback(@[[NSNull null], events]);
}

//设置常量给JavaScript进行调用
- (NSDictionary *)constantsToExport {
  //此处定义的常量为js通知的通知名
  return @{@"receiveNotificationName": @"receive_notification_test"};
}

//对外提供通知方法,接收js的通知
RCT_EXPORT_METHOD(startReceiveNotification:(NSString *)name) {
  NSLog(@"--%s--, ----%@", __FUNCTION__, name);
  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(calendarEventReminderReceived:)
                                               name:name
                                             object:nil];
  
  [[NSNotificationCenter defaultCenter] postNotificationName:name object:@"nnnnnnnn"];
}
//进行设置发送事件通知给js端
- (void)calendarEventReminderReceived:(NSNotification *)notification {
  NSString *name = notification.object;
  [self.bridge.eventDispatcher sendAppEventWithName:@"EventNotification"
                                               body:@{@"name": name}];
}

RN完整代码:

//与原生数据交互
import React, { Component } from 'react';
import {
    AppRegistry,
    StyleSheet,
    View,
    TouchableOpacity,
    NativeModules,
    Text,
    NativeAppEventEmitter
} from 'react-native';

//用来调用Test1ViewController中的方法
var caManager = require('NativeModules').Test1ViewController;
var date = new Date();
var count = 0;
//创建一个监听收到的通知
var listener = NativeAppEventEmitter.addListener(
    'EventNotification', //监听的通知名称
    (reminder) => console.log(reminder.name, '收到的通知')
);

export default class Rninteractive extends Component {
    constructor(props) {
        super(props);
        this.state = {
            text:'Welcome to React Native!',
            name: '快来看看哦',
        };
    }
    //将要开始布局,只执行一次
    componentWillMount() {
        console.log('componentWillMount111');
    }
    //是否需要更新
    shouldComponentUpdate() {
        console.log('shouldComponentUpdate222')
        return true;
    }
    //布局完成,只执行一次
    componentDidMount() {
        console.log('componentDidMount333');
    }
    //将要更新布局
    componentWillUpdate() {
        console.log('componentWillUpdate444');
    }
    //更新完成
    componentDidUpdate() {
        console.log('componentDidUpdate555');
    }
    //接收属性
    componentWillReceiveProps() {
        console.log('componentWillReceiveProps666');
    }
    //卸载
    componentWillUnmount() {
        //卸载的时候要取消监听
        listener.remove();
    }

    render(){
        var welcomeText = this.state.text;
        var wename = this.state.name;
        var valued = this.props.soure.map(
            soure => soure,
        );
        console.log('render', valued);
        return(
            <View style={styles.contentView}>
                <TouchableOpacity onPress={this.touchtestNormalEvent}>
                    <Text>
                        {welcomeText}
                    </Text>
                </TouchableOpacity>
                <TouchableOpacity onPress={this.touchtestDictEvent}>
                    <Text>
                        {wename}
                    </Text>
                </TouchableOpacity>
                <TouchableOpacity onPress={this.touchtestCallbackEvent}>
                    <Text>
                        与原生ios传递回调函数
                    </Text>
                </TouchableOpacity>
                <TouchableOpacity onPress={this.touchreceiveNotification}>
                    <Text>
                        与原生ios通知方式传递
                    </Text>
                </TouchableOpacity>
            </View>
        )
    }

    //普通传递数据
    touchtestNormalEvent = () => {
        console.log('touchtestNormalEvent');
        caManager.testNormalEvent('超级无敌帅', '老子是逗比');
    };

    //字典传递
    touchtestDictEvent = () => {
        console.log('touchtestDictEvent');
        caManager.testDictEvent('超级无敌帅2号', {'name': 'wwww', 'age': 18, 'date': date})
    };

    //闭包回调
    touchtestCallbackEvent = () => {
        console.log('touchtestCallbackEvent');
        caManager.testCallbackEvent('超级无敌帅3号', (error, events) => {
            if (error) {
                console.log('error =', error)
            }else {
                console.log('events =', events)
            }
        })
    };

    //通知传递
    touchreceiveNotification = () => {
        //receiveNotificationName通知名由iOS原生提供
        caManager.startReceiveNotification(caManager.receiveNotificationName);
    }
}

const styles = StyleSheet.create({
   contentView: {
       flex: 1,
       backgroundColor: '#aff1af',
       alignItems: 'center',
       justifyContent: 'center',
   }
});

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

推荐阅读更多精彩内容