今天,記錄一下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
安卓待寫....