今天,记录一下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.基本调用:

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

RN:

  1. CalendarManager.addEventOne('周少停');

2.字符串+字典:

  1. 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.字符串+日期:

  1. 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:

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

4.点击调原生+回调

  1. 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

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

RN:

  1. try{
  2. var events=await CalendarManager.testCallbackEventTwo();
  3. alert(events)
  4. }catch(e){
  5. console.error(e);
  6. }

5.使用原生定义的常量

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

RN:

  1. alert(CalendarManager.ValueOne)

完整代码:

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

安卓待写....


iOS原生和React-Native之间的交互1的更多相关文章

  1. iOS原生 和 react native视图混编

    在iOS原生功能中加入RN,请看之前 写的 RN与iOS交互系列文章.本篇只讲下视图混编. 关键点只有二: 1.通过 RCTRootView 加载RN视图. 2.RN中,只需要AppRegistry. ...

  2. 一个资深iOS开发者对于React Native的看法

    一个资深iOS开发者对于React Native的看法 当我第一次尝试ReactNative的时候,我觉得这只是网页开发者涉足原生移动应用领域的歪门邪道.   我认为一个js开发者可以使用javasc ...

  3. 现有iOS项目集成React Native过程记录

    在<Mac系统下React Native环境搭建>配置了RN的开发环境,然后,本文记录在现有iOS项目集成React Native的过程,官方推荐使用Cocoapods,项目一开始也是使用 ...

  4. iOS 写给iOS开发者的React Native学习路线(转)

    我是一名iOS开发者,断断续续一年前开始接触React Native,最近由于工作需要,专职学习React Native也有一个多月了.网络上知识资源非常的多,但能让人豁然开朗.迅速学习的还是少数,我 ...

  5. 写给iOS开发者的React Native学习路线(转)

    我是一名iOS开发者,断断续续一年前开始接触React Native,最近由于工作需要,专职学习React Native也有一个多月了.网络上知识资源非常的多,但能让人豁然开朗.迅速学习的还是少数,我 ...

  6. [转] 一个资深iOS开发者对于React Native的看法

    当我第一次尝试ReactNative的时候,我觉得这只是网页开发者涉足原生移动应用领域的歪门邪道. 我认为一个js开发者可以使用javascript来构建iPhone应用确实是一件很酷的事情,但是我很 ...

  7. Android原生嵌入React Native

    1.首先集成的项目目录 我使用的是直接按照react-native init Project 的格式来导入的,也就是说,我的Android项目目录是跟node_modules是在一个目录下的. 我们i ...

  8. Flutter介绍 - Flutter,H5,React Native之间的对比

    Flutter介绍 Flutter是Google推出的开源移动应用开发框架.开发者可以通过开发一套代码同时运行在iOS和Android平台. 它使用Dart语言进行开发,并且最终编译成各个平台的Nat ...

  9. 《React Native 精解与实战》书籍连载「iOS 平台与 React Native 混合开发」

    此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...

  10. 【React Native】在原生和React Native间通信(RN调用原生)

    一.从React Native中调用原生方法(原生模块) 原生模块是JS中也可以使用的Objective-C类.一般来说这样的每一个模块的实例都是在每一次通过JS bridge通信时创建的.他们可以导 ...

随机推荐

  1. windows下进程间通信与线程间通信

    进程间通信: 1.文件映射(Memory-Mapped Files) 文件映射(Memory-Mapped Files)能使进程把文件内容当作进程地址区间一块内存那样来对待.因此,进程不必使用文件I/ ...

  2. 牛客练习赛30-A/C

    链接:https://ac.nowcoder.com/acm/contest/216/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K ...

  3. UI界面按钮增强

    (我是菜鸟,知道的少) 1.有HTML页面代码的,可以编辑 <%@page language="abap" %> <%@extension name=" ...

  4. 从使用角度看 ReentrantLock 和 Condition

    java 语言中谈到锁,少不了比较一番 synchronized 和 ReentrantLock 的原理,本文不作分析,只是简单介绍一下 ReentrantLock 的用法,从使用中推测其内部的一些原 ...

  5. js正则表达式取{}中的值

    var reg = /[^\{}]*\{(.*)\}[^\}]*/; var str = "1111{122}"; console.log(str.replace(reg,'$1' ...

  6. kiss prefix paleo,per,pen,pan,para out 1

      1● paleo 2● per 3● pen 4● pan 5● para   1★ paleo 古   2★ para ,辅助,在旁边   3★ pan 广泛的   4★ per 假,坏,自始自 ...

  7. POJ 1390 Blocks(记忆化搜索+dp)

    POJ 1390 Blocks 砌块 时限:5000 MS   内存限制:65536K 提交材料共计: 6204   接受: 2563 描述 你们中的一些人可能玩过一个叫做“积木”的游戏.一行有n个块 ...

  8. Resharper插件如何启用原VS的智能提示

    第一步:vs2015选择工具—>选项—>文本编辑器—>C#—>常规—>语句结束,勾选自动列出成员,如下图: 第二步: 关闭Resharper智能提示,并设置为Visual ...

  9. Yii2.0 数据库查询 [ 2.0 版本 ]

    下面介绍一下 Yii2.0 对数据库 查询的一些简单的操作 User::find()->all(); 此方法返回所有数据: User::findOne($id); 此方法返回 主键 id=1 的 ...

  10. PropertiesUtil 获取文件属性值

    有时候不要把一些属性值写死在代码中,而是写在配置在文件中,方便更改 PropertiesUtil工具类:读取key-value形式的配置文件,根据key获得value值  1.测试类 public c ...