美文网首页
iOS 和React Native 交互

iOS 和React Native 交互

作者: 沙长健 | 来源:发表于2017-03-21 16:07 被阅读994次

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了
                 })
             }
        })
    }

文章来源:http://www.cnblogs.com/shaoting/p/6392390.html

相关文章

网友评论

      本文标题:iOS 和React Native 交互

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