iOS原生和React-Native之间的交互1
今天,记录一下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
- //
- // CalendarManager.h
- // rnAndN
- //
- // Created by Shaoting Zhou on 2017/2/10.
- // Copyright © 2017年 Facebook. All rights reserved.
- //
- #import <Foundation/Foundation.h>
- #import <React/RCTBridgeModule.h>
- #import <React/RCTLog.h>
- @interface CalendarManager : NSObject<RCTBridgeModule>
- @end
b.CalendarManager.m配置,为了实现该协议,需要含有一个宏:RCT_EXPORT_MODULE(),
- //
- // CalendarManager.m
- // rnAndN
- //
- // Created by Shaoting Zhou on 2017/2/10.
- // Copyright © 2017年 Facebook. All rights reserved.
- //
- #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.基本调用:
- CalendarManager.m
- // 接收传过来的 NSString
- RCT_EXPORT_METHOD(addEventOne:(NSString *)name){
- NSLog(@"接收传过来的NSString+NSString: %@", name);
- }
RN:
- CalendarManager.addEventOne('周少停');
2.字符串+字典:
- CalendarManager.m
- // 接收传过来的 NSString + NSDictionary
- RCT_EXPORT_METHOD(addEventTwo:(NSString *)name details:(NSDictionary *)details)
- {
- RCTLogInfo(@"接收传过来的NSString+NSDictionary: %@ %@", name, details);
- }
RN:
- CalendarManager.addEventTwo('周少停',{job:'programmer'});
3.字符串+日期:
- 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]);
- }
RN:
- CalendarManager.addEventThree('周少停',19910730);
4.点击调原生+回调
- CalendarManager.m
- // 对外提供调用方法,演示Callback
- RCT_EXPORT_METHOD(testCallbackEventOne:(NSString *)name callback:(RCTResponseSenderBlock)callback)
- {
- NSLog(@"%@",name);
- NSArray *events=@[@"1", @"2", @"3",@"4"]; //准备回调回去的数据
- callback(@[[NSNull null],events]);
- }
RN:
- // 传原生一个字符串 + 回调
- callBackOne = ()=>{
- CalendarManager.testCallbackEventOne(('我是RN给原生的'),(error, events) => {
- if (error) {
- console.error(error);
- } else {
- alert(events)
- }
- })
- }
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
- - (NSDictionary *)constantsToExport
- {
- return @{ @"ValueOne": @"我是从原生定义的~" };
- }
RN:
- alert(CalendarManager.ValueOne)
完整代码:
- CalendarManager.m
- //
- // CalendarManager.m
- // rnAndN
- //
- // Created by Shaoting Zhou on 2017/2/10.
- // Copyright © 2017年 Facebook. All rights reserved.
- //
- #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:
- /**
- * Sample React Native App
- * https://github.com/facebook/react-native
- * @flow
- */
- 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);
演示效果和demo源码:https://github.com/pheromone/IOS-native-and-React-native-interaction
另:因为react native并不提供清除缓存功能,所以只能通过react native调用原生来实现计算缓存大小和清除缓存功能:
iOS:
- //
- // CalendarManager.m
- // rnAndN
- //
- // Created by Shaoting Zhou on 2017/2/10.
- // Copyright © 2017年 Facebook. All rights reserved.
- //
- #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了
- })
- }
- })
- }
iOS清除缓存源码可以参考该微博项目中的:https://github.com/pheromone/react_native_weibo
安卓待写....
iOS原生和React-Native之间的交互1的更多相关文章
- iOS原生 和 react native视图混编
在iOS原生功能中加入RN,请看之前 写的 RN与iOS交互系列文章.本篇只讲下视图混编. 关键点只有二: 1.通过 RCTRootView 加载RN视图. 2.RN中,只需要AppRegistry. ...
- 一个资深iOS开发者对于React Native的看法
一个资深iOS开发者对于React Native的看法 当我第一次尝试ReactNative的时候,我觉得这只是网页开发者涉足原生移动应用领域的歪门邪道. 我认为一个js开发者可以使用javasc ...
- 现有iOS项目集成React Native过程记录
在<Mac系统下React Native环境搭建>配置了RN的开发环境,然后,本文记录在现有iOS项目集成React Native的过程,官方推荐使用Cocoapods,项目一开始也是使用 ...
- iOS 写给iOS开发者的React Native学习路线(转)
我是一名iOS开发者,断断续续一年前开始接触React Native,最近由于工作需要,专职学习React Native也有一个多月了.网络上知识资源非常的多,但能让人豁然开朗.迅速学习的还是少数,我 ...
- 写给iOS开发者的React Native学习路线(转)
我是一名iOS开发者,断断续续一年前开始接触React Native,最近由于工作需要,专职学习React Native也有一个多月了.网络上知识资源非常的多,但能让人豁然开朗.迅速学习的还是少数,我 ...
- [转] 一个资深iOS开发者对于React Native的看法
当我第一次尝试ReactNative的时候,我觉得这只是网页开发者涉足原生移动应用领域的歪门邪道. 我认为一个js开发者可以使用javascript来构建iPhone应用确实是一件很酷的事情,但是我很 ...
- Android原生嵌入React Native
1.首先集成的项目目录 我使用的是直接按照react-native init Project 的格式来导入的,也就是说,我的Android项目目录是跟node_modules是在一个目录下的. 我们i ...
- Flutter介绍 - Flutter,H5,React Native之间的对比
Flutter介绍 Flutter是Google推出的开源移动应用开发框架.开发者可以通过开发一套代码同时运行在iOS和Android平台. 它使用Dart语言进行开发,并且最终编译成各个平台的Nat ...
- 《React Native 精解与实战》书籍连载「iOS 平台与 React Native 混合开发」
此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...
- 【React Native】在原生和React Native间通信(RN调用原生)
一.从React Native中调用原生方法(原生模块) 原生模块是JS中也可以使用的Objective-C类.一般来说这样的每一个模块的实例都是在每一次通过JS bridge通信时创建的.他们可以导 ...
随机推荐
- windows下进程间通信与线程间通信
进程间通信: 1.文件映射(Memory-Mapped Files) 文件映射(Memory-Mapped Files)能使进程把文件内容当作进程地址区间一块内存那样来对待.因此,进程不必使用文件I/ ...
- 牛客练习赛30-A/C
链接:https://ac.nowcoder.com/acm/contest/216/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K ...
- UI界面按钮增强
(我是菜鸟,知道的少) 1.有HTML页面代码的,可以编辑 <%@page language="abap" %> <%@extension name=" ...
- 从使用角度看 ReentrantLock 和 Condition
java 语言中谈到锁,少不了比较一番 synchronized 和 ReentrantLock 的原理,本文不作分析,只是简单介绍一下 ReentrantLock 的用法,从使用中推测其内部的一些原 ...
- js正则表达式取{}中的值
var reg = /[^\{}]*\{(.*)\}[^\}]*/; var str = "1111{122}"; console.log(str.replace(reg,'$1' ...
- 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 假,坏,自始自 ...
- POJ 1390 Blocks(记忆化搜索+dp)
POJ 1390 Blocks 砌块 时限:5000 MS 内存限制:65536K 提交材料共计: 6204 接受: 2563 描述 你们中的一些人可能玩过一个叫做“积木”的游戏.一行有n个块 ...
- Resharper插件如何启用原VS的智能提示
第一步:vs2015选择工具—>选项—>文本编辑器—>C#—>常规—>语句结束,勾选自动列出成员,如下图: 第二步: 关闭Resharper智能提示,并设置为Visual ...
- Yii2.0 数据库查询 [ 2.0 版本 ]
下面介绍一下 Yii2.0 对数据库 查询的一些简单的操作 User::find()->all(); 此方法返回所有数据: User::findOne($id); 此方法返回 主键 id=1 的 ...
- PropertiesUtil 获取文件属性值
有时候不要把一些属性值写死在代码中,而是写在配置在文件中,方便更改 PropertiesUtil工具类:读取key-value形式的配置文件,根据key获得value值 1.测试类 public c ...