React Native在設計之初,就考慮到了React Native提供的API,不可以徹底的覆蓋平臺對應的全部API.所以在React Native中能夠方便的調用Native的方法,Android上面對應Java方法,IOS上對應Object-C方法。
有的時候在處理數據庫,多線程上面,使用Native加的方便。
下面就以調用IOS系統的Alert
爲例,看下怎麼使用JavaScript代碼調用Object-C的Native方法的。react
RCT
是ReaCT的縮寫,React Native中Object-C相關的命名均以RCT開頭。RCTBridgeModule
是定義好的protocol
,實現該協議的類,會自動註冊到Object-C對應的Bridge中。
Object-C Bridge上層負責與Object-C通訊,下層負責和JavaScript Bridge通訊,而JavaScript Bridge負責和JavaScript通訊.
這樣,經過Object-C Bridge和JavaScript Bridge就能夠實現JavaScript和Object-C的相互調用。
先要定義一個類:RNIOSAlert
用來現實RCTBridgeModule
協議。git
#import <Foundation/Foundation.h> #import <UIKit/UIKit.h> #import "RCTBridgeModule.h" @interface RNIOSAlert : NSObject<RCTBridgeModule> @end
全部實現RCTBridgeModule
的類都必須顯示的include
宏命令:RCT_EXPORT_MODULE()
。RCT_EXPORT_MODULE
的做用是:自動註冊一個Module,當Object-c Bridge加載的時候。這個Module能夠在JavaScript Bridge中調用。RCT_EXPORT_MODULE
宏命令的定義:github
#define RCT_EXPORT_MODULE(js_name) \ RCT_EXTERN void RCTRegisterModule(Class); \ + (NSString *)moduleName { return @#js_name; } \ + (void)load { RCTRegisterModule(self); }
能夠看到RCT_EXPORT_MODULE
接受字符串做爲其Module的名稱,若是不設置名稱的話默認就使用類名做爲Modul的名稱。
引入RCT_EXPORT_MODULE
:數據庫
#import "RNIOSAlert.h" @implementation RNIOSAlert RCT_EXPORT_MODULE(); @end
RCT_EXPORT_METHOD
是用來定義被JavaScript調用的方法的宏。RCT_EXTERN_METHOD
調用了宏RCT_EXTERN_REMAP_METHOD
,最終調用宏RCT_EXTERN_REMAP_METHOD
。RCT_EXTERN_REMAP_METHOD
的代碼實現:react-native
#define RCT_EXTERN_REMAP_METHOD(js_name, method) \ + (NSArray<NSString *> *)RCT_CONCAT(__rct_export__, \ RCT_CONCAT(js_name, RCT_CONCAT(__LINE__, __COUNTER__))) { \ return @[@#js_name, @#method]; \ }
它的做用是在RCT_EXPORT_MODULE
定義的Module下面,定義一個能夠被JavaScript調用的方法。RCT_EXPORT_MODULE
的使用,須要寫入方法名,參數以及完整的實現,例如:多線程
#import "RNIOSAlert.h" @implementation RNIOSAlert RCT_EXPORT_MODULE(); RCT_EXPORT_METHOD(show:(NSString *)msg){ UIAlertView * alertView=[[UIAlertView alloc] initWithTitle:@"react-native" message:msg delegate:nil cancelButtonTitle:@"關閉" otherButtonTitles:nil, nil]; [alertView show]; } @end
在JavaScript中調用Object-C定義的方法,須要先導入NativeModules
,再使用RNIOSAlert
:
完整代碼以下:spa
import { StyleSheet, Text, View, NativeModules, TouchableOpacity } from "react-native"; var RNIOSAlert = NativeModules.RNIOSAlert; class RNIos extends Component { render() { return ( <View style={styles.container}> <TouchableOpacity onPress={()=>RNIOSAlert.show('from react native ')}> <Text>Alert</Text> </TouchableOpacity> </View> ); } }
成功調用Alert
:線程
RCT_EXPORT_METHOD
支持須要JSON所支持的數據類型,JavaScript中的參數與Object-C的參數的對應關係。設計
string -> NSStringcode
number -> (NSInteger,float,double,CGFloat,NSNumber)
boolean -> (BOOL,NSNumber)
array -> NSArray
object -> NSDictionary
function -> RCTResponseSenderBlock
另外React Navite還提供了RCTConvert
,詳情的代碼能夠參照 https://github.com/facebook/react-native/blob/master/React/Base/RCTConvert.h,他的做用能夠把傳入的參數轉換爲須要的數據類型。
好比咱們在Object-C中定義一個方法,該方法接收NSDictionary
參數:
RCT_EXPORT_METHOD(showTime:(NSDictionary*)dict){ NSDate * date =[RCTConvert NSDate:dict[@"time"]]; UIAlertView * alertView=[[UIAlertView alloc] initWithTitle:@"react-native" message:[date description] delegate:nil cancelButtonTitle:@"關閉" otherButtonTitles:nil, nil]; [alertView show]; }
這裏使用RCTConvert
直接把NSDictionary中的值轉換爲NSDate.
在JavaScript中的調用showTime
方法:
...... <TouchableOpacity onPress={()=> { var date = new Date(); RNIOSAlert.showTime( { time: date.getTime() } ) }}> <Text>Time</Text> </TouchableOpacity> ......