日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

【REACT NATIVE 系列教程之十二】REACT NATIVE(JS/ES)与IOS(OBJECT-C)交互通信

發布時間:2023/12/15 javascript 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【REACT NATIVE 系列教程之十二】REACT NATIVE(JS/ES)与IOS(OBJECT-C)交互通信 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一用到跨平臺的引擎必然要有引擎與各平臺原生進行交互通信的需要。那么Himi先講解React Native與iOS之間的通信交互。

? ? ? ?本篇主要分為兩部分講解:(關于其中講解的OC語法等不介紹,不懂的請自行學習)

? ? ? ?1. React Native 訪問iOS?

? ? ? ?2. iOS訪問React Native

?

? ? 一:React Native 訪問iOS

1.?我們想要JS調用OC函數,就要實現一個“RCTBridgeModule”協議的Objective-C類

所以首先我們先創建一個oc新類, ?Himi這里起名為:TestOJO ?(O: object-c, J: javaScript )

2. TestOJO.h

#import?<Foundation/Foundation.h> #import?"RCTBridgeModule.h"@interface?TestOJO?:?NSObject??<RCTBridgeModule>@end


引入:#import “RCTBridgeModule.h” ??且使用?<RCTBridgeModule> 接口,

3.?為了實現RCTBridgeModule協議,類需要包含RCT_EXPORT_MODULE()宏(這個宏也可以添加一個參數用來指定在Javascript中訪問這個模塊的名字。如果你不指定,默認就會使用這個Objective-C類的名字。)

4. 在TestOJO.m中添加如下:

RCT_EXPORT_MODULE(); //橋接到Javascript的方法返回值類型必須是void。React?Native的橋接操作是異步的,所以要返回結果給Javascript,必須通過回調或者觸發事件來進行 RCT_EXPORT_METHOD(j2oFun1:(NSString?*)dataString?dateNumber:(int)dateNumber) {NSLog(@"js?call?iOS?function?j2oFun1\n?dataString:?%@?|dateNumber?:%d",dataString,dateNumber); }


想要將oc的函數導出給js進行調用,那么就需要進行聲明。聲明通過RCT_EXPORT_METHOD()宏來實現:

j2oFun1:函數名,后續是兩個參數,分別是NSString 和 int 類型數據。

調用成功后,我們輸出這兩個傳來的值到控制臺。

注意:Javascript調用的OC函數,此函數返回值類型必須是void。由于React Native的橋接操作是異步的,所以要返回結果給Javascript,必須通過回調參數進行 后續詳細講解。

從js傳來的參數我們可以依靠自動類型轉換的特性,跳過手動的類型轉換(RCTConvert,下面詳細介紹),在定義函數參數類型時,直接寫上對應想要的數據類型,例如NSData等。

5. 下面看js調用的代碼段:

var?TestOJO?=?require('react-native').NativeModules.TestOJO; TestOJO.j2oFun1('Himi',?12321);

var TestOJO=require(‘react-native’).NativeModules.TestOJO;(將OC注冊進來的模塊取出)

TestOJO.j2oFun1(‘Himi’, 12321);(調用模塊中的對應函數,且將參數進行傳入)

6. 我們來看一段復雜的數據通信

OC 代碼段(導出函數):

#import?"RCTConvert.h" RCT_EXPORT_METHOD(j2oFun2:(NSDictionary?*)details) {NSString?*name?=?[RCTConvert?NSString:details[@"name"]];NSNumber?*age?=?[RCTConvert?NSNumber:details[@"age"]];NSArray?*?array?=[RCTConvert?NSArray:details[@"array"]];NSLog(@"js?call?iOS?function?j2oFun2\n?name:?%@?|?age?:%@",?name,?[age?stringValue]);for?(int?i?=?0;?i<[array?count];?i++)?{NSLog(@"array:?第%d個元素:%@",i,array[i]);} }

需要注意的是,引入了”RCTConvert”類,作用:

RCTConvert提供了一系列輔助函數,用來接收一個JSON值并轉換到原生Objective-C類型或類。

JS代碼段:(調用OC函數)

TestOJO.j2oFun2({name:'Himi',age:12,array:['hi,Himi','i,m','a?array!']});


7. 我們下面來利用回調參數來得到訪問OC的函數得到其返回值

RCT_EXPORT_METHOD(j2oCallbackEvent:(NSString?*)jsString?callback:(RCTResponseSenderBlock)callback) {NSLog(@"js?call?iOS?function:??j2oCallbackEvent?\n?jsString:%@",jsString);NSArray?*events?=?[[NSArray?alloc]?initWithObjects:@"Himi",@"12321",?nil];callback(@[[NSNull?null],?events]); }


RCTResponseSenderBlock 是種特殊的參數類型——回調函數,通過此參數可以實現當JS訪問的OC函數后,并能將此OC函數的返回值傳遞給JS。

RCTResponseSenderBlock 只接受一個參數(傳遞給JavaScript回調函數的參數數組)

callback函數:第一個參數是一個錯誤對象(沒有發生錯誤的時候為null),而剩下的部分是函數的返回值。

下面我們來看JS調用代碼段:

TestOJO.j2oCallbackEvent('Himi',(error,callBackEvents)=>{if?(error)?{console.error(error);}?else?{Alert.alert('J2O帶返回值',?'數組的三個值:\n[0]:'+callBackEvents[0]+'\n[1]:'+callBackEvents[1]+'\n[2]:'+callBackEvents[2]);} });


二:?iOS訪問React Native

1. ?我們如果想要OC訪問JS,給JavaScript發送事件通知,我們需要使用RCTEventDispatcher的函數,與RCTBridge的實例

因此我們需要先做準備,TestOJO.h:

#import?"RCTEventDispatcher.h" @synthesize?bridge?=?_bridge;

bridge: 是RCTBridge 的實例,且在我們使用的接口?RCTBridgeModule中。

OC訪問JS的代碼段:

[self.bridge.eventDispatcher?sendAppEventWithName:@"eventName"?body:@{@"name":@"Himi",@"age":?@12}];

第一個參數:事件名

第二個參數(body):傳入的參數

其中@{}是定義不可變的字典的快捷實例方式,因此我們也可以改成如下形式:

NSDictionary?*?direct?=@{@"name":?@"Himi",@"age":?@12};[self.bridge.eventDispatcher?sendAppEventWithName:@"eventName"?body:direct];


下面來看JS中定義OC調用的函數:

其實所謂OC能響應JS,是JS進行了對應函數的綁定監聽。因此我們需要利用?NativeAppEventEmitter 組件,利用其addListener進行注冊監聽!因此我們需要引入進來這個模塊,

import?{...NativeAppEventEmitter...}?from?'react-native'; var?o2cFun?=?NativeAppEventEmitter.addListener('eventName',(para)?=>?Alert.alert('被OC觸發','字典數據:\n?name:'+para.name+'\n?age:'+para.age) );


var o2cFun : 將綁定好的監聽事件引用交給此變量保存。

addListener:

第一個參數:事件名

第二個參數:響應函數

注意:利用addListener進行監聽,一定要對應有取消監聽!要保持一一對應的好習慣。

且通常取消監聽都在componentWillUnmount函數中進行。如下:

??componentWillUnmount(){o2cFun.remove();}


其中對于原理并沒有詳細的介紹,這里推薦兩篇文章,童鞋們可以詳細的閱讀一下,這里不贅述:

http://www.jianshu.com/p/203b91a77174

http://reactnative.cn/docs/0.21/native-modules-ios.html#content

下面給出源碼:

TestOJO.h:

// //??TestOJO.h //??MyProject // //??Created?by?Himi?on?16/6/2. //??Copyright??2016年?Facebook.?All?rights?reserved. // #import?<Foundation/Foundation.h> #import?"RCTBridgeModule.h" @interface?TestOJO?:?NSObject??<RCTBridgeModule> @end


TestOJO.m:

// //??TestOJO.m //??MyProject // //??Created?by?Himi?on?16/6/2. //??Copyright??2016年?Facebook.?All?rights?reserved. // #import?"TestOJO.h" //RCTConvert類支持的的類型也都可以使用,RCTConvert還提供了一系列輔助函數,用來接收一個JSON值并轉換到原生Objective-C類型或類。 #import?"RCTConvert.h" //本地模塊也可以給JavaScript發送事件通知。最直接的方式是使用eventDispatcher #import?"RCTEventDispatcher.h" @implementation?TestOJO //====================================[JS?->??OC]======================================= RCT_EXPORT_MODULE(); //橋接到Javascript的方法返回值類型必須是void。React?Native的橋接操作是異步的,所以要返回結果給Javascript,必須通過回調或者觸發事件來進行 RCT_EXPORT_METHOD(j2oFun1:(NSString?*)dataString?dateNumber:(int)dateNumber) {NSLog(@"js?call?iOS?function?j2oFun1\n?dataString:?%@?|dateNumber?:%d",dataString,dateNumber); } RCT_EXPORT_METHOD(j2oFun2:(NSDictionary?*)details) {NSString?*name?=?[RCTConvert?NSString:details[@"name"]];NSNumber?*age?=?[RCTConvert?NSNumber:details[@"age"]];NSArray?*?array?=[RCTConvert?NSArray:details[@"array"]];NSLog(@"js?call?iOS?function?j2oFun2\n?name:?%@?|?age?:%@",?name,?[age?stringValue]);for?(int?i?=?0;?i<[array?count];?i++)?{NSLog(@"array:?第%d個元素:%@",i,array[i]);}} //帶回調函數?RCTResponseSenderBlock?,提供將返回值傳回給js //RCTResponseSenderBlock?只接受一個參數->傳遞給JavaScript回調函數的參數數組 RCT_EXPORT_METHOD(j2oCallbackEvent:(NSString?*)jsString?callback:(RCTResponseSenderBlock)callback) {NSLog(@"js?call?iOS?function:??j2oCallbackEvent?\n?jsString:%@",jsString);NSArray?*events?=?[[NSArray?alloc]?initWithObjects:@"Himi",@"12321",?nil];callback(@[[NSNull?null],?events]); } //====================================[OC?->??JS]======================================= @synthesize?bridge?=?_bridge; //此函數是為了測試OC->JS過程,觸發事件的函數 RCT_EXPORT_METHOD(emitterO2J) {[self?ocCallJsFun]; } -?(void)ocCallJsFun {NSDictionary?*?direct?=@{@"name":?@"Himi",@"age":?@12};[self.bridge.eventDispatcher?sendAppEventWithName:@"eventName"?body:direct];//??[self.bridge.eventDispatcher?sendAppEventWithName:@"eventName"?body:@{@"name":@"Himi",@"age":?@12}];} @end


Main.js:

import?React,?{?Component?}?from?'react'; import?{View,Text,StyleSheet,Image,Alert,NativeAppEventEmitter,//引用NativeAppEventEmitter組件進行監聽Native端派發的事件}?from?'react-native'; var?TestOJO?=?require('react-native').NativeModules.TestOJO; var?o2cFun?=?NativeAppEventEmitter.addListener('eventName',(para)?=>?Alert.alert('被OC觸發','字典數據:\n?name:'+para.name+'\n?age:'+para.age) ); //?千萬不要忘記忘記取消訂閱,?通常在componentWillUnmount函數中實現。 //?o2cFun.remove(); export?default?class?Main?extends?Component?{constructor(props)?{super(props);this.state?=?{selectedTab:'home'};}componentWillUnmount(){o2cFun.remove();}render()?{return?(<View?style={{flex:?1,?alignItems:?'center'}}><Text?style={styles.himiTextStyle}>Himi?React?Native?系列教程</Text><TextonPress={()=>{TestOJO.j2oFun1('Himi',?12321);TestOJO.j2oFun2({name:'Himi',age:12,array:['hi,Himi','i,m','a?array!']});TestOJO.j2oCallbackEvent('Himi',(error,callBackEvents)=>{if?(error)?{console.error(error);}?else?{Alert.alert('J2O帶返回值',?'數組的三個值:\n[0]:'+callBackEvents[0]+'\n[1]:'+callBackEvents[1]+'\n[2]:'+callBackEvents[2]);}});}}style={styles.himiTextStyle}>JS?->?OC</Text><TextonPress={()=>{TestOJO.emitterO2J();}}style={styles.himiTextStyle}>JS?->?OC?->?JS</Text></View>);} }; var?styles?=?StyleSheet.create({himiTextStyle:{backgroundColor:'#eee',color:'#f00',fontSize:30,marginTop:70,}, });

下面是運行效果:(點擊看動態圖,主要看演示過程與控制臺輸出哦!)

注意:

1.點擊JS->OC 后,會調用三個函數哦

2.點擊JS->OC->JS, 先是通過JS->OC的臨時函數,觸發OC->JS的過程!


總結

以上是生活随笔為你收集整理的【REACT NATIVE 系列教程之十二】REACT NATIVE(JS/ES)与IOS(OBJECT-C)交互通信的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。