国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > iOS > 正文

REACT NATIVE(JS/ES)與IOS(OBJECT-C)交互通信

2019-11-08 00:22:18
字體:
來源:轉載
供稿:網友
本站文章均為 李華明Himi 原創,

一用到跨平臺的引擎必然要有引擎與各平臺原生進行交互通信的需要。那么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

123456#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中添加如下:

1234567RCT_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調用的代碼段:

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

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

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

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

OC 代碼段(導出函數):

12345678910111213#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,[agestringValue]);    for(inti=0;i<[arraycount];i++){    NSLog(@"array: 第%d個元素:%@",i,array[i]);  }}

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

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

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

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

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

123456RCT_EXPORT_METHOD(j2oCallbackEvent:(NSString*)jsString callback:(RCTResponseSenderBlock)callback){  NSLog(@"js call iOS function:  j2oCallbackEvent /n jsString:%@",jsString);  NSArray*events=[[NSArrayalloc] initWithObjects:@"Himi",@"12321",nil];  callback(@[[NSNullnull],events]);}

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

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

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

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

1234567TestOJO.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:

123#import "RCTEventDispatcher.h" @synthesizebridge=_bridge;

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

OC訪問JS的代碼段:

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

第一個參數:事件名

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

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

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

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

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

12345678910import {  ...  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函數中進行。如下:

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

 

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

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

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

下面給出源碼

TestOJO.h:

1234567891011121314////  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:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576////  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"  @implementationTestOJO  //====================================[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,[agestringValue]);    for(inti=0;i<[arraycount];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=[[NSArrayalloc] initWithObjects:@"Himi",@"12321",nil];  callback(@[[NSNullnull],events]);}   //====================================[OC ->  JS]=======================================@synthesizebridge=_bridge; //此函數是為了測試OC->JS過程,觸發事件的函數RCT_EXPORT_METHOD(emitterO2J){  [selfocCallJsFun];} -(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:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475importReact,{Component}from'react';import{  View,  Text,  StyleSheet,  Image,  Alert,  NativeAppEventEmitter,//引用NativeAppEventEmitter組件進行監聽Native端派發的事件}from'react-native'; varTestOJO=require('react-native').NativeModules.TestOJO; varo2cFun=NativeAppEventEmitter.addListener(  'eventName',  (para)=>Alert.alert('被OC觸發','字典數據:/n name:'+para.name+'/n age:'+para.age));// 千萬不要忘記忘記取消訂閱, 通常在componentWillUnmount函數中實現。// o2cFun.remove(); exportdefaultclassMainextendsComponent{constructor(props){super(props);this.state={      selectedTab:'home'    };}  componentWillUnmount(){    o2cFun.remove();  }  render(){    return(      <Viewstyle={{flex:1,alignItems:'center'}}>        <Textstyle={styles.himiTextStyle}>HimiReactNative系列教程</Text>         <Text          onPress={()=>{              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>         <Text          onPress={()=>{              TestOJO.emitterO2J();          }}          style={styles.himiTextStyle}>JS->OC->JS        </Text>         </View>    );  }}; varstyles=StyleSheet.create({  himiTextStyle:{    backgroundColor:'#eee',    color:'#f00',    fontSize:30,    marginTop:70,  },});

 

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

user918

注意:

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

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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 农安县| 青岛市| 武山县| 瑞昌市| 沙田区| 五大连池市| 仪征市| 株洲市| 那坡县| 山东省| 台南县| 八宿县| 新蔡县| 磐安县| 普宁市| 格尔木市| 旬阳县| 清丰县| 大城县| 色达县| 文昌市| 修武县| 镇沅| 分宜县| 万年县| 西乡县| 社旗县| 丽江市| 阳西县| 抚宁县| 右玉县| 慈溪市| 孙吴县| 奇台县| 合肥市| 抚州市| 黄浦区| 安福县| 视频| 中卫市| 灯塔市|