RN和iOS的交互其实就是数据相互传输, 想明白这一点就成功了一大半了!!!
举个例子:RN中还有一些无法实现的功能, 因此可以,你可以将RN中的数据传递给iOS, iOS处理完后再传递给RN就可以了
准备:
终端新建一个�react-native项目或者使用上一篇文章建立的demo.
a.先使用Xcode打开,新建一个CalendarManager类,集成自NSObject即可.先在CalendarManager.h中导入相关类和实现协议RCTBridgeModule
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTLog.h>
@interface CalendarManager : NSObject<RCTBridgeModule>
@end
b.CalendarManager.m配置,为了实现该协议,需要含有一个宏:RCT_EXPORT_MODULE(),
#import "CalendarManager.h"
@implementation CalendarManager
RCT_EXPORT_MODULE();
c.react-native 通过NativeModules来实现传输和接受消息:
import {
AppRegistry,
StyleSheet,
Text,
View,
NativeModules
} from 'react-native';
var CalendarManager = NativeModules.CalendarManager;
1.1基本调用(将RN中的数据(字符串)传递给iOS)(iOS端代码):
CalendarManager.m
// 接收传过来的 NSString
RCT_EXPORT_METHOD(addEventOne:(NSString *)name){
NSLog(@"接收传过来的NSString+NSString: %@", name);
}
1.2将RN中的数据(字符串)传递给iOS(RN端代码):
CalendarManager.addEventOne('周少停');
2.1将RN中的数据(字符串+字典:)传递给iOS(iOS端代码):
CalendarManager.m
// 接收传过来的 NSString + NSDictionary
RCT_EXPORT_METHOD(addEventTwo:(NSString *)name details:(NSDictionary *)details)
{
RCTLogInfo(@"接收传过来的NSString+NSDictionary: %@ %@", name, details);
}
2.2将RN中的数据(字符串+字典:)传递给iOS(RN端代码):
CalendarManager.addEventTwo('周少停',{job:'programmer'});
3.1将RN中的数据(字符串+日期)传递给iOS字符串+日期(iOS段代码):
CalendarManager.m
// 接收传过来的 NSString + date日期
RCT_EXPORT_METHOD(addEventThree:(NSString *)name date:(NSDate *)date)
{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;
[formatter setDateFormat:@"yyyy-MM-dd"];
RCTLogInfo(@"接收传过来的NSString+NSDictionary: %@ %@", name, [formatter stringFromDate:date]);
}
3.2将RN中的数据(字符串+日期)传递给iOS字符串+日期(RN段代码):
CalendarManager.addEventThree('周少停',19910730);
4.1将RN中的字符串传递给iOS + 回调(将iOS中的数据传递给RN) (iOS端代码)
CalendarManager.m
// 对外提供调用方法,演示Callback
RCT_EXPORT_METHOD(testCallbackEventOne:(NSString *)name callback:(RCTResponseSenderBlock)callback)
{
NSLog(@"%@",name);
NSArray *events=@[@"1", @"2", @"3",@"4"]; //准备回调回去的数据
callback(@[[NSNull null],events]);
}
4.2将RN中的字符串传递给iOS + 回调(将iOS中的数据传递给RN) (RN端代码)
// 传原生一个字符串 + 回调
callBackOne = ()=>{
CalendarManager.testCallbackEventOne(('我是RN给原生的'),(error, events) => {
if (error) {
console.error(error);
} else {
alert(events)
}
})
}
5.1Promises(将iOS端的数据选择性的传递给RN)(iOS端代码)
CalendarManager.m
// 对外提供调用方法,演示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);
}
}
5.2将iOS端的数据选择性的传递给RN(RN端代码):
try{
var events=await CalendarManager.testCallbackEventTwo();
alert(events)
}catch(e){
console.error(e);
}
6.1使用原生定义的常量(直接通过RN端直接方位iOS中的常量)(iOS端代码)
CalendarManager.m
- (NSDictionary *)constantsToExport
{
return @{ @"ValueOne": @"我是从原生定义的~" };
}
6.2使用原生定义的常量(直接通过RN端直接方位iOS中的常量)(RN端代码)
alert(CalendarManager.ValueOne)
完整代码:
CalendarManager.m
#import "CalendarManager.h"
@implementation CalendarManager
RCT_EXPORT_MODULE();
// 接收传过来的 NSString
RCT_EXPORT_METHOD(addEventOne:(NSString *)name){
NSLog(@"接收传过来的NSString+NSString: %@", name);
}
// 接收传过来的 NSString + NSDictionary
RCT_EXPORT_METHOD(addEventTwo:(NSString *)name details:(NSDictionary *)details)
{
RCTLogInfo(@"接收传过来的NSString+NSDictionary: %@ %@", name, details);
}
// 接收传过来的 NSString + date日期
RCT_EXPORT_METHOD(addEventThree:(NSString *)name date:(NSDate *)date)
{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;
[formatter setDateFormat:@"yyyy-MM-dd"];
RCTLogInfo(@"接收传过来的NSString+NSDictionary: %@ %@", name, [formatter stringFromDate:date]);
}
// 对外提供调用方法,演示Callback
RCT_EXPORT_METHOD(testCallbackEventOne:(NSString *)name callback:(RCTResponseSenderBlock)callback)
{
NSLog(@"%@",name);
NSArray *events=@[@"1", @"2", @"3",@"4"]; //准备回调回去的数据
callback(@[[NSNull null],events]);
}
//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);
}
}
- (NSDictionary *)constantsToExport
{
return @{ @"ValueOne": @"我是从原生定义的~" };
}
@end
RN:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
NativeModules
} from 'react-native';
var CalendarManager = NativeModules.CalendarManager;
export default class NativeAddRN extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome} onPress={()=>this.passValueToNativeOne()}>点击往原生传字符串</Text>
<Text style={styles.welcome} onPress={()=>this.passValueToNativeTwo()}>点击往原生传字符串+字典</Text>
<Text style={styles.welcome} onPress={()=>this.passValueToNativeThree()}>点击往原生传字符串+日期</Text>
<Text style={styles.welcome} onPress={()=>this.callBackOne()}>点击调原生+回调</Text>
<Text style={styles.welcome} onPress={()=>this.callBackTwo()}>Promises</Text>
<Text style={styles.welcome} onPress={()=>this.useNativeValue()}>使用原生定义的常量</Text>
</View>
);
}
// 传原生一个字符串
passValueToNativeOne = ()=>{
CalendarManager.addEventOne('周少停');
}
// 传原生一个字符串 + 字典
passValueToNativeTwo = ()=>{
CalendarManager.addEventTwo('周少停',{job:'programmer'});
}
// 传原生一个字符串 + 日期
passValueToNativeThree = ()=>{
CalendarManager.addEventThree('周少停',19910730);
}
// 传原生一个字符串 + 回调
callBackOne = ()=>{
CalendarManager.testCallbackEventOne(('我是RN给原生的'),(error, events) => {
if (error) {
console.error(error);
} else {
alert(events)
}
})
}
//Promise回调
async callBackTwo(){
try{
var events=await CalendarManager.testCallbackEventTwo();
alert(events)
}catch(e){
console.error(e);
}
}
//使用原生定义的常量
useNativeValue = ()=>{
alert(CalendarManager.ValueOne)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
marginTop:100
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
AppRegistry.registerComponent('NativeAddRN', () => NativeAddRN);
另:因为react native并不提供清除缓存功能,所以只能通过react native调用原生来实现计算缓存大小和清除缓存功能:
iOS:
#import "CalendarManager.h"
@implementation CalendarManager
RCT_EXPORT_MODULE();
// 清理缓存
RCT_EXPORT_METHOD(cleanCache:(RCTResponseSenderBlock)callback)
{
NSURLCache *httpCache = [NSURLCache sharedURLCache];
[httpCache removeAllCachedResponses];
NSUInteger cache = [httpCache currentDiskUsage];
callback(@[[NSNull null],@(cache)]);
}
// 计算缓存
RCT_EXPORT_METHOD(cacheSize:(RCTResponseSenderBlock)callback)
{
NSURLCache *httpCache = [NSURLCache sharedURLCache];
NSUInteger cache = [httpCache currentDiskUsage];
callback(@[[NSNull null],@(cache)]);
}
@end
RN:
再进入清除缓存界面时,就计算缓存大小:
componentWillMount() {
CalendarManager.cacheSize((error, events) => {
if (error) {
console.error(error);
} else {
this.setState({
cache:Math.round(events/1024) //缓存大小
})
}
})
}
清除缓存按钮响应时间:
clearRom =()=>{
CalendarManager.cleanCache((error, events) => {
if (error) {
console.error(error);
} else {
this.setState({
cache:0 //这里本应该是清除之后的数据Math.round(events/1024).应该是0才对,但是总是清不干净,我就直接置为0了
})
}
})
}