今天,记录一下iOS原生和React-Native之间的交互.如果第一次接触最好先移步至 http://www.cnblogs.com/shaoting/p/6388502.html 先看一下怎么在iOS原生中集成react-native模块.

iOS原生和React-Native之间的交互主要通过NativeModules实现.

先看RN->iOS原生

开发环境版本:

准备:

     终端新建一个react-native项目或者使用上一篇文章建立的demo.

a.先使用Xcode打开,新建一个CalendarManager类,集成自NSObject即可.先在CalendarManager.h中导入相关类和实现协议RCTBridgeModule

 1 //
 2 //  CalendarManager.h
 3 //  rnAndN
 4 //
 5 //  Created by Shaoting Zhou on 2017/2/10.
 6 //  Copyright © 2017年 Facebook. All rights reserved.
 7 //
 8 
 9 #import <Foundation/Foundation.h>
10 #import <React/RCTBridgeModule.h>
11 #import <React/RCTLog.h>
12 @interface CalendarManager : NSObject<RCTBridgeModule>
13 
14 @end

b.CalendarManager.m配置,为了实现该协议,需要含有一个宏:RCT_EXPORT_MODULE(),

 1 //
 2 //  CalendarManager.m
 3 //  rnAndN
 4 //
 5 //  Created by Shaoting Zhou on 2017/2/10.
 6 //  Copyright © 2017年 Facebook. All rights reserved.
 7 //
 8 
 9 #import "CalendarManager.h"
10 
11 @implementation CalendarManager
12 
13 RCT_EXPORT_MODULE();

c.react-native 通过NativeModules来实现传输和接受消息:

1  import {
2     AppRegistry,
3      StyleSheet,
4     Text,
5     View,
6    NativeModules
7   } from 'react-native';
8  var CalendarManager = NativeModules.CalendarManager;

1.基本调用:

CalendarManager.m
// 接收传过来的 NSString
RCT_EXPORT_METHOD(addEventOne:(NSString *)name){
  NSLog(@"接收传过来的NSString+NSString: %@", name);
}

RN:

CalendarManager.addEventOne('周少停');

2.字符串+字典:

CalendarManager.m
1 // 接收传过来的 NSString + NSDictionary
2 RCT_EXPORT_METHOD(addEventTwo:(NSString *)name details:(NSDictionary *)details)
3 {
4   RCTLogInfo(@"接收传过来的NSString+NSDictionary: %@ %@", name, details);
5 }

RN:

1 CalendarManager.addEventTwo('周少停',{job:'programmer'});

3.字符串+日期:

CalendarManager.m
1 // 接收传过来的 NSString + date日期
2 RCT_EXPORT_METHOD(addEventThree:(NSString *)name date:(NSDate *)date)
3 {
4    NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;
5    [formatter setDateFormat:@"yyyy-MM-dd"];
6   RCTLogInfo(@"接收传过来的NSString+NSDictionary: %@ %@", name, [formatter stringFromDate:date]);
7 }

RN:

CalendarManager.addEventThree('周少停',19910730);

4.点击调原生+回调

CalendarManager.m
1 //  对外提供调用方法,演示Callback
2 RCT_EXPORT_METHOD(testCallbackEventOne:(NSString *)name callback:(RCTResponseSenderBlock)callback)
3 {
4   NSLog(@"%@",name);
5   NSArray *events=@[@"1", @"2", @"3",@"4"]; //准备回调回去的数据
6   callback(@[[NSNull null],events]);
7 }

RN:

 1     // 传原生一个字符串 + 回调
 2     callBackOne = ()=>{
 3         CalendarManager.testCallbackEventOne(('我是RN给原生的'),(error, events) => {
 4             if (error) {
 5                 console.error(error);
 6             } else {
 7                 alert(events)
 8             }
 9         })
10     }

5.Promises

CalendarManager.m
//Promises
//  对外提供调用方法,演示Promise使用
RCT_REMAP_METHOD(testCallbackEventTwo,
                 resolver:(RCTPromiseResolveBlock)resolve
                 rejecter:(RCTPromiseRejectBlock)reject)
{
  NSArray *events =@[@"one ",@"two ",@"three"];//准备回调回去的数据
  if (events) {
    resolve(events);
  } else {
    NSError *error=[NSError errorWithDomain:@"我是Promise回调错误信息..." code:101 userInfo:nil];
    reject(@"no_events", @"There were no events", error);
  }
}

RN:

try{
            var events=await CalendarManager.testCallbackEventTwo();
            alert(events)
        }catch(e){
            console.error(e);
        }

5.使用原生定义的常量

CalendarManager.m
1 - (NSDictionary *)constantsToExport
2 {
3   return @{ @"ValueOne": @"我是从原生定义的~" };
4 }

RN:

alert(CalendarManager.ValueOne)

完整代码:

CalendarManager.m
 1 //
 2 //  CalendarManager.m
 3 //  rnAndN
 4 //
 5 //  Created by Shaoting Zhou on 2017/2/10.
 6 //  Copyright © 2017年 Facebook. All rights reserved.
 7 //
 8 
 9 #import "CalendarManager.h"
10 
11 @implementation CalendarManager
12 
13 RCT_EXPORT_MODULE();
14 
15 // 接收传过来的 NSString
16 RCT_EXPORT_METHOD(addEventOne:(NSString *)name){
17   NSLog(@"接收传过来的NSString+NSString: %@", name);
18 }
19 // 接收传过来的 NSString + NSDictionary
20 RCT_EXPORT_METHOD(addEventTwo:(NSString *)name details:(NSDictionary *)details)
21 {
22   RCTLogInfo(@"接收传过来的NSString+NSDictionary: %@ %@", name, details);
23 }
24 
25 // 接收传过来的 NSString + date日期
26 RCT_EXPORT_METHOD(addEventThree:(NSString *)name date:(NSDate *)date)
27 {
28    NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;
29    [formatter setDateFormat:@"yyyy-MM-dd"];
30   RCTLogInfo(@"接收传过来的NSString+NSDictionary: %@ %@", name, [formatter stringFromDate:date]);
31 }
32 
33 //  对外提供调用方法,演示Callback
34 RCT_EXPORT_METHOD(testCallbackEventOne:(NSString *)name callback:(RCTResponseSenderBlock)callback)
35 {
36   NSLog(@"%@",name);
37   NSArray *events=@[@"1", @"2", @"3",@"4"]; //准备回调回去的数据
38   callback(@[[NSNull null],events]);
39 }
40 
41 //Promises
42 //  对外提供调用方法,演示Promise使用
43 RCT_REMAP_METHOD(testCallbackEventTwo,
44                  resolver:(RCTPromiseResolveBlock)resolve
45                  rejecter:(RCTPromiseRejectBlock)reject)
46 {
47   NSArray *events =@[@"one ",@"two ",@"three"];//准备回调回去的数据
48   if (events) {
49     resolve(events);
50   } else {
51     NSError *error=[NSError errorWithDomain:@"我是Promise回调错误信息..." code:101 userInfo:nil];
52     reject(@"no_events", @"There were no events", error);
53   }
54 }
55 
56 - (NSDictionary *)constantsToExport
57 {
58   return @{ @"ValueOne": @"我是从原生定义的~" };
59 }
60 
61 
62 @end

RN:

 1 /**
 2  * Sample React Native App
 3  * https://github.com/facebook/react-native
 4  * @flow
 5  */
 6 
 7 import React, { Component } from 'react';
 8 import {
 9     AppRegistry,
10     StyleSheet,
11     Text,
12     View,
13     NativeModules
14 } from 'react-native';
15 var CalendarManager = NativeModules.CalendarManager;
16 
17 
18 export default class NativeAddRN extends Component {
19     render() {
20         return (
21             <View style={styles.container}>
22               <Text style={styles.welcome} onPress={()=>this.passValueToNativeOne()}>点击往原生传字符串</Text>
23               <Text style={styles.welcome} onPress={()=>this.passValueToNativeTwo()}>点击往原生传字符串+字典</Text>
24               <Text style={styles.welcome} onPress={()=>this.passValueToNativeThree()}>点击往原生传字符串+日期</Text>
25               <Text style={styles.welcome} onPress={()=>this.callBackOne()}>点击调原生+回调</Text>
26               <Text style={styles.welcome} onPress={()=>this.callBackTwo()}>Promises</Text>
27               <Text style={styles.welcome} onPress={()=>this.useNativeValue()}>使用原生定义的常量</Text>
28             </View>
29         );
30     }
31     // 传原生一个字符串
32     passValueToNativeOne = ()=>{
33         CalendarManager.addEventOne('周少停');
34     }
35     // 传原生一个字符串 + 字典
36     passValueToNativeTwo = ()=>{
37         CalendarManager.addEventTwo('周少停',{job:'programmer'});
38     }
39     // 传原生一个字符串 + 日期
40     passValueToNativeThree = ()=>{
41         CalendarManager.addEventThree('周少停',19910730);
42     }
43     // 传原生一个字符串 + 回调
44     callBackOne = ()=>{
45         CalendarManager.testCallbackEventOne(('我是RN给原生的'),(error, events) => {
46             if (error) {
47                 console.error(error);
48             } else {
49                 alert(events)
50             }
51         })
52     }
53     //Promise回调
54     async callBackTwo(){
55         try{
56             var events=await CalendarManager.testCallbackEventTwo();
57             alert(events)
58         }catch(e){
59             console.error(e);
60         }
61     }
62     //使用原生定义的常量
63     useNativeValue = ()=>{
64         alert(CalendarManager.ValueOne)
65     }
66 
67 }
68 
69 const styles = StyleSheet.create({
70     container: {
71         flex: 1,
72         marginTop:100
73     },
74     welcome: {
75         fontSize: 20,
76         textAlign: 'center',
77         margin: 10,
78     },
79     instructions: {
80         textAlign: 'center',
81         color: '#333333',
82         marginBottom: 5,
83     },
84 });
85 
86 AppRegistry.registerComponent('NativeAddRN', () => NativeAddRN);

演示效果和demo源码:https://github.com/pheromone/IOS-native-and-React-native-interaction

 另:因为react native并不提供清除缓存功能,所以只能通过react native调用原生来实现计算缓存大小和清除缓存功能:

iOS:

 1 //
 2 //  CalendarManager.m
 3 //  rnAndN
 4 //
 5 //  Created by Shaoting Zhou on 2017/2/10.
 6 //  Copyright © 2017年 Facebook. All rights reserved.
 7 //
 8 
 9 #import "CalendarManager.h"
10 @implementation CalendarManager
11 
12 RCT_EXPORT_MODULE();
13 
14 //  清理缓存
15 RCT_EXPORT_METHOD(cleanCache:(RCTResponseSenderBlock)callback)
16 {
17   NSURLCache *httpCache = [NSURLCache sharedURLCache];
18   [httpCache removeAllCachedResponses];
19   NSUInteger cache = [httpCache currentDiskUsage];
20   callback(@[[NSNull null],@(cache)]);
21 }
22 // 计算缓存
23  RCT_EXPORT_METHOD(cacheSize:(RCTResponseSenderBlock)callback)
24  {
25    NSURLCache *httpCache = [NSURLCache sharedURLCache];
26    NSUInteger cache = [httpCache currentDiskUsage];
27    callback(@[[NSNull null],@(cache)]);
28  }
29 @end

RN:

再进入清除缓存界面时,就计算缓存大小:

 1     componentWillMount() {
 2         CalendarManager.cacheSize((error, events) => {
 3             if (error) {
 4                 console.error(error);
 5             } else {
 6                 this.setState({
 7                     cache:Math.round(events/1024)   //缓存大小
 8                 })
 9             }
10         })
11     }

清除缓存按钮响应时间:

 1     clearRom  =()=>{
 2         CalendarManager.cleanCache((error, events) => {
 3             if (error) {
 4                 console.error(error);
 5             } else {
 6                 this.setState({
 7                     cache:0  //这里本应该是清除之后的数据Math.round(events/1024).应该是0才对,但是总是清不干净,我就直接置为0了
 8                 })
 9             }
10         })
11     }

 iOS清除缓存源码可以参考该微博项目中的:https://github.com/pheromone/react_native_weibo

 

安卓待写....