iOS原生和React-Native之間的交互1

今天,記錄一下iOS原生和React-Native之間的交互.若是第一次接觸最好先移步至 http://www.cnblogs.com/shaoting/p/6388502.html 先看一下怎麼在iOS原生中集成react-native模塊.javascript

iOS原生和React-Native之間的交互主要經過NativeModules實現.html

先看RN->iOS原生java

開發環境版本:react

準備:git

     終端新建一個react-native項目或者使用上一篇文章創建的demo.github

a.先使用Xcode打開,新建一個CalendarManager類,集成自NSObject便可.先在CalendarManager.h中導入相關類和實現協議RCTBridgeModulereact-native

 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來實現傳輸和接受消息:async

1  import {
2     AppRegistry,
3      StyleSheet,
4     Text,
5     View,
6    NativeModules
7   } from 'react-native';
8  var CalendarManager = NativeModules.CalendarManager;

1.基本調用:flex

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

 

安卓待寫....

相關文章
相關標籤/搜索