React-Native 學習RN和iOS交互

一:iOS傳遞數(shù)據到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:使用通知方式傳遞數(shù)據到RN

iOS代碼發(fā)送通知:
//需要包含的頭文件
#import <React/RCTEventDispatcher.h>
#import <React/RCTBridge.h>
[self.bridge.eventDispatcher sendAppEventWithName:@"EventNotification"
                                               body:@{@"name": @"nnnnnnn"}];
RN代碼接收通知:
//創(chuàng)建一個監(jiān)聽收到的通知减俏,需要組件NativeAppEventEmitter
var listener = NativeAppEventEmitter.addListener(
    'EventNotification', //監(jiān)聽的通知名稱
    (reminder) => console.log(reminder.name, '收到的通知')
);

二:RN傳遞數(shù)據到iOS
iOS提供外調的接口崔挖,需要實現(xiàn)RCTBridgeModule協(xié)議

//  必須實現(xiàn)
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提供的方法傳遞數(shù)據

//普通傳遞數(shù)據
    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;
}

//  必須實現(xiàn)
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"];
}
//進行設置發(fā)送事件通知給js端
- (void)calendarEventReminderReceived:(NSNotification *)notification {
  NSString *name = notification.object;
  [self.bridge.eventDispatcher sendAppEventWithName:@"EventNotification"
                                               body:@{@"name": name}];
}

RN完整代碼:

//與原生數(shù)據交互
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;
//創(chuàng)建一個監(jiān)聽收到的通知
var listener = NativeAppEventEmitter.addListener(
    'EventNotification', //監(jiān)聽的通知名稱
    (reminder) => console.log(reminder.name, '收到的通知')
);

export default class Rninteractive extends Component {
    constructor(props) {
        super(props);
        this.state = {
            text:'Welcome to React Native!',
            name: '快來看看哦',
        };
    }
    //將要開始布局素标,只執(zhí)行一次
    componentWillMount() {
        console.log('componentWillMount111');
    }
    //是否需要更新
    shouldComponentUpdate() {
        console.log('shouldComponentUpdate222')
        return true;
    }
    //布局完成,只執(zhí)行一次
    componentDidMount() {
        console.log('componentDidMount333');
    }
    //將要更新布局
    componentWillUpdate() {
        console.log('componentWillUpdate444');
    }
    //更新完成
    componentDidUpdate() {
        console.log('componentDidUpdate555');
    }
    //接收屬性
    componentWillReceiveProps() {
        console.log('componentWillReceiveProps666');
    }
    //卸載
    componentWillUnmount() {
        //卸載的時候要取消監(jiān)聽
        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傳遞回調函數(shù)
                    </Text>
                </TouchableOpacity>
                <TouchableOpacity onPress={this.touchreceiveNotification}>
                    <Text>
                        與原生ios通知方式傳遞
                    </Text>
                </TouchableOpacity>
            </View>
        )
    }

    //普通傳遞數(shù)據
    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);
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末萍悴,一起剝皮案震驚了整個濱河市头遭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌癣诱,老刑警劉巖计维,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異撕予,居然都是意外死亡鲫惶,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門实抡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來欠母,“玉大人,你說我怎么就攤上這事吆寨∫蘸” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵鸟废,是天一觀的道長。 經常有香客問我姑荷,道長盒延,這世上最難降的妖魔是什么缩擂? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮添寺,結果婚禮上胯盯,老公的妹妹穿的比我還像新娘。我一直安慰自己计露,他們只是感情好博脑,可當我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著票罐,像睡著了一般叉趣。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上该押,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天疗杉,我揣著相機與錄音,去河邊找鬼蚕礼。 笑死烟具,一個胖子當著我的面吹牛,可吹牛的內容都是我干的奠蹬。 我是一名探鬼主播朝聋,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼囤躁!你這毒婦竟也來了冀痕?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤割以,失蹤者是張志新(化名)和其女友劉穎金度,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體严沥,經...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡猜极,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了消玄。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片跟伏。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖翩瓜,靈堂內的尸體忽然破棺而出受扳,到底是詐尸還是另有隱情,我是刑警寧澤兔跌,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布勘高,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏华望。R本人自食惡果不足惜蕊蝗,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望赖舟。 院中可真熱鬧蓬戚,春花似錦、人聲如沸宾抓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽石洗。三九已至幢泼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間劲腿,已是汗流浹背旭绒。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留焦人,地道東北人挥吵。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像花椭,于是被迫代替她去往敵國和親忽匈。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內容