• 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

     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

    安卓待写....

  • 相关阅读:
    WIN10系统如何取消右下角的通知菜单,通知图标
    1.1.6版本Druid连接MSSQLServer 2008 R2报错The query timeout value -1 is not valid. #2210
    第一次使用Android Studio时你应该知道的一切配置(三):gradle项目构建
    CentOS 7 Tomcat服务的安装与配置
    centos7中使用yum安装tomcat以及它的启动、停止、重启
    centos7更改为启动桌面或命令行模式
    gradle新建工程,多项目依赖,聚合工程
    Gradle构建多模块项目(转)
    3分钟搞定SpringBoot+Mybatis+druid多数据源和分布式事务
    Spring MVC+Mybatis 多数据源配置
  • 原文地址:https://www.cnblogs.com/shaoting/p/6392390.html
Copyright © 2020-2023  润新知